| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/allocation-site-scopes.h" | 8 #include "src/allocation-site-scopes.h" |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 case LookupIterator::JSPROXY: | 136 case LookupIterator::JSPROXY: |
| 137 return JSProxy::GetPropertyWithHandler( | 137 return JSProxy::GetPropertyWithHandler( |
| 138 it->GetJSProxy(), it->GetReceiver(), it->name()); | 138 it->GetJSProxy(), it->GetReceiver(), it->name()); |
| 139 case LookupIterator::INTERCEPTOR: { | 139 case LookupIterator::INTERCEPTOR: { |
| 140 MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithInterceptor( | 140 MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithInterceptor( |
| 141 it->GetHolder(), it->GetReceiver(), it->name()); | 141 it->GetHolder(), it->GetReceiver(), it->name()); |
| 142 if (!maybe_result.is_null()) return maybe_result; | 142 if (!maybe_result.is_null()) return maybe_result; |
| 143 if (it->isolate()->has_pending_exception()) return maybe_result; | 143 if (it->isolate()->has_pending_exception()) return maybe_result; |
| 144 break; | 144 break; |
| 145 } | 145 } |
| 146 case LookupIterator::ACCESS_CHECK: { | 146 case LookupIterator::ACCESS_CHECK: |
| 147 if (it->HasAccess(v8::ACCESS_GET)) break; | 147 if (it->HasAccess(v8::ACCESS_GET)) break; |
| 148 return JSObject::GetPropertyWithFailedAccessCheck(it); | 148 return JSObject::GetPropertyWithFailedAccessCheck(it); |
| 149 } | |
| 150 case LookupIterator::PROPERTY: | 149 case LookupIterator::PROPERTY: |
| 151 if (it->HasProperty()) { | 150 if (it->HasProperty()) { |
| 152 switch (it->property_kind()) { | 151 switch (it->property_kind()) { |
| 153 case LookupIterator::ACCESSOR: | 152 case LookupIterator::ACCESSOR: |
| 154 return GetPropertyWithAccessor( | 153 return GetPropertyWithAccessor( |
| 155 it->GetReceiver(), it->name(), | 154 it->GetReceiver(), it->name(), |
| 156 it->GetHolder(), it->GetAccessors()); | 155 it->GetHolder(), it->GetAccessors()); |
| 157 case LookupIterator::DATA: | 156 case LookupIterator::DATA: |
| 158 return it->GetDataValue(); | 157 return it->GetDataValue(); |
| 159 } | 158 } |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 Handle<Object> argv[] = { value }; | 559 Handle<Object> argv[] = { value }; |
| 561 RETURN_ON_EXCEPTION( | 560 RETURN_ON_EXCEPTION( |
| 562 isolate, | 561 isolate, |
| 563 Execution::Call(isolate, setter, receiver, ARRAY_SIZE(argv), argv), | 562 Execution::Call(isolate, setter, receiver, ARRAY_SIZE(argv), argv), |
| 564 Object); | 563 Object); |
| 565 return value; | 564 return value; |
| 566 } | 565 } |
| 567 | 566 |
| 568 | 567 |
| 569 static bool FindAllCanReadHolder(LookupIterator* it) { | 568 static bool FindAllCanReadHolder(LookupIterator* it) { |
| 569 it->skip_interceptor(); |
| 570 it->skip_access_check(); |
| 570 for (; it->IsFound(); it->Next()) { | 571 for (; it->IsFound(); it->Next()) { |
| 571 if (it->state() == LookupIterator::PROPERTY && | 572 if (it->state() == LookupIterator::PROPERTY && |
| 572 it->HasProperty() && | 573 it->HasProperty() && |
| 573 it->property_kind() == LookupIterator::ACCESSOR) { | 574 it->property_kind() == LookupIterator::ACCESSOR) { |
| 574 Handle<Object> accessors = it->GetAccessors(); | 575 Handle<Object> accessors = it->GetAccessors(); |
| 575 if (accessors->IsAccessorInfo()) { | 576 if (accessors->IsAccessorInfo()) { |
| 576 if (AccessorInfo::cast(*accessors)->all_can_read()) return true; | 577 if (AccessorInfo::cast(*accessors)->all_can_read()) return true; |
| 577 } else if (accessors->IsAccessorPair()) { | 578 } else if (accessors->IsAccessorPair()) { |
| 578 if (AccessorPair::cast(*accessors)->all_can_read()) return true; | 579 if (AccessorPair::cast(*accessors)->all_can_read()) return true; |
| 579 } | 580 } |
| 580 } | 581 } |
| 581 } | 582 } |
| 582 return false; | 583 return false; |
| 583 } | 584 } |
| 584 | 585 |
| 585 | 586 |
| 586 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck( | 587 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck( |
| 587 LookupIterator* it) { | 588 LookupIterator* it) { |
| 588 Handle<JSObject> checked = Handle<JSObject>::cast(it->GetHolder()); | 589 Handle<JSObject> checked = Handle<JSObject>::cast(it->GetHolder()); |
| 589 if (FindAllCanReadHolder(it)) { | 590 if (FindAllCanReadHolder(it)) { |
| 590 return GetPropertyWithAccessor( | 591 return GetPropertyWithAccessor( |
| 591 it->GetReceiver(), it->name(), it->GetHolder(), it->GetAccessors()); | 592 it->GetReceiver(), it->name(), it->GetHolder(), it->GetAccessors()); |
| 592 } | 593 } |
| 593 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_GET); | 594 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_GET); |
| 594 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); | 595 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); |
| 595 return it->factory()->undefined_value(); | 596 return it->factory()->undefined_value(); |
| 596 } | 597 } |
| 597 | 598 |
| 598 | 599 |
| 599 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( | 600 PropertyAttributes JSObject::GetPropertyAttributesWithFailedAccessCheck( |
| 600 Handle<JSObject> object, | 601 LookupIterator* it) { |
| 601 LookupResult* result, | 602 Handle<JSObject> checked = Handle<JSObject>::cast(it->GetHolder()); |
| 602 Handle<Name> name, | 603 if (FindAllCanReadHolder(it)) return it->property_details().attributes(); |
| 603 bool check_prototype) { | 604 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_HAS); |
| 604 LookupIterator::Configuration configuration = check_prototype | |
| 605 ? LookupIterator::CHECK_DERIVED | |
| 606 : LookupIterator::CHECK_OWN_REAL; | |
| 607 LookupIterator it(object, name, object, configuration); | |
| 608 if (FindAllCanReadHolder(&it)) return it.property_details().attributes(); | |
| 609 it.isolate()->ReportFailedAccessCheck(object, v8::ACCESS_HAS); | |
| 610 // TODO(yangguo): Issue 3269, check for scheduled exception missing? | 605 // TODO(yangguo): Issue 3269, check for scheduled exception missing? |
| 611 return ABSENT; | 606 return ABSENT; |
| 612 } | 607 } |
| 613 | 608 |
| 614 | 609 |
| 615 static bool FindAllCanWriteHolder(LookupResult* result, | 610 static bool FindAllCanWriteHolder(LookupResult* result, |
| 616 Handle<Name> name, | 611 Handle<Name> name, |
| 617 bool check_prototype) { | 612 bool check_prototype) { |
| 618 if (result->IsInterceptor()) { | 613 if (result->IsInterceptor()) { |
| 619 result->holder()->LookupOwnRealNamedProperty(name, result); | 614 result->holder()->LookupOwnRealNamedProperty(name, result); |
| (...skipping 2442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3062 LookupResult result(isolate); | 3057 LookupResult result(isolate); |
| 3063 object->LookupRealNamedPropertyInPrototypes(name, &result); | 3058 object->LookupRealNamedPropertyInPrototypes(name, &result); |
| 3064 if (result.IsFound()) { | 3059 if (result.IsFound()) { |
| 3065 switch (result.type()) { | 3060 switch (result.type()) { |
| 3066 case NORMAL: | 3061 case NORMAL: |
| 3067 case FIELD: | 3062 case FIELD: |
| 3068 case CONSTANT: | 3063 case CONSTANT: |
| 3069 *done = result.IsReadOnly(); | 3064 *done = result.IsReadOnly(); |
| 3070 break; | 3065 break; |
| 3071 case INTERCEPTOR: { | 3066 case INTERCEPTOR: { |
| 3072 PropertyAttributes attr = GetPropertyAttributeWithInterceptor( | 3067 LookupIterator it(object, name, handle(result.holder())); |
| 3073 handle(result.holder()), object, name, true); | 3068 PropertyAttributes attr = GetPropertyAttributes(&it); |
| 3074 *done = !!(attr & READ_ONLY); | 3069 *done = !!(attr & READ_ONLY); |
| 3075 break; | 3070 break; |
| 3076 } | 3071 } |
| 3077 case CALLBACKS: { | 3072 case CALLBACKS: { |
| 3078 *done = true; | 3073 *done = true; |
| 3079 if (!result.IsReadOnly()) { | 3074 if (!result.IsReadOnly()) { |
| 3080 Handle<Object> callback_object(result.GetCallbackObject(), isolate); | 3075 Handle<Object> callback_object(result.GetCallbackObject(), isolate); |
| 3081 return SetPropertyWithCallback(object, name, value, | 3076 return SetPropertyWithCallback(object, name, value, |
| 3082 handle(result.holder()), | 3077 handle(result.holder()), |
| 3083 callback_object, strict_mode); | 3078 callback_object, strict_mode); |
| (...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3720 | 3715 |
| 3721 | 3716 |
| 3722 MaybeHandle<Object> JSProxy::DeleteElementWithHandler( | 3717 MaybeHandle<Object> JSProxy::DeleteElementWithHandler( |
| 3723 Handle<JSProxy> proxy, uint32_t index, DeleteMode mode) { | 3718 Handle<JSProxy> proxy, uint32_t index, DeleteMode mode) { |
| 3724 Isolate* isolate = proxy->GetIsolate(); | 3719 Isolate* isolate = proxy->GetIsolate(); |
| 3725 Handle<String> name = isolate->factory()->Uint32ToString(index); | 3720 Handle<String> name = isolate->factory()->Uint32ToString(index); |
| 3726 return JSProxy::DeletePropertyWithHandler(proxy, name, mode); | 3721 return JSProxy::DeletePropertyWithHandler(proxy, name, mode); |
| 3727 } | 3722 } |
| 3728 | 3723 |
| 3729 | 3724 |
| 3730 PropertyAttributes JSProxy::GetPropertyAttributeWithHandler( | 3725 PropertyAttributes JSProxy::GetPropertyAttributesWithHandler( |
| 3731 Handle<JSProxy> proxy, | 3726 Handle<JSProxy> proxy, |
| 3732 Handle<JSReceiver> receiver, | 3727 Handle<Object> receiver, |
| 3733 Handle<Name> name) { | 3728 Handle<Name> name) { |
| 3734 Isolate* isolate = proxy->GetIsolate(); | 3729 Isolate* isolate = proxy->GetIsolate(); |
| 3735 HandleScope scope(isolate); | 3730 HandleScope scope(isolate); |
| 3736 | 3731 |
| 3737 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3732 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 3738 if (name->IsSymbol()) return ABSENT; | 3733 if (name->IsSymbol()) return ABSENT; |
| 3739 | 3734 |
| 3740 Handle<Object> args[] = { name }; | 3735 Handle<Object> args[] = { name }; |
| 3741 Handle<Object> result; | 3736 Handle<Object> result; |
| 3742 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 3737 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3804 return static_cast<PropertyAttributes>(attributes); | 3799 return static_cast<PropertyAttributes>(attributes); |
| 3805 } | 3800 } |
| 3806 | 3801 |
| 3807 | 3802 |
| 3808 PropertyAttributes JSProxy::GetElementAttributeWithHandler( | 3803 PropertyAttributes JSProxy::GetElementAttributeWithHandler( |
| 3809 Handle<JSProxy> proxy, | 3804 Handle<JSProxy> proxy, |
| 3810 Handle<JSReceiver> receiver, | 3805 Handle<JSReceiver> receiver, |
| 3811 uint32_t index) { | 3806 uint32_t index) { |
| 3812 Isolate* isolate = proxy->GetIsolate(); | 3807 Isolate* isolate = proxy->GetIsolate(); |
| 3813 Handle<String> name = isolate->factory()->Uint32ToString(index); | 3808 Handle<String> name = isolate->factory()->Uint32ToString(index); |
| 3814 return GetPropertyAttributeWithHandler(proxy, receiver, name); | 3809 return GetPropertyAttributesWithHandler(proxy, receiver, name); |
| 3815 } | 3810 } |
| 3816 | 3811 |
| 3817 | 3812 |
| 3818 void JSProxy::Fix(Handle<JSProxy> proxy) { | 3813 void JSProxy::Fix(Handle<JSProxy> proxy) { |
| 3819 Isolate* isolate = proxy->GetIsolate(); | 3814 Isolate* isolate = proxy->GetIsolate(); |
| 3820 | 3815 |
| 3821 // Save identity hash. | 3816 // Save identity hash. |
| 3822 Handle<Object> hash(proxy->GetIdentityHash(), isolate); | 3817 Handle<Object> hash(proxy->GetIdentityHash(), isolate); |
| 3823 | 3818 |
| 3824 if (proxy->IsJSFunctionProxy()) { | 3819 if (proxy->IsJSFunctionProxy()) { |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4346 } else if (value_changed) { | 4341 } else if (value_changed) { |
| 4347 EnqueueChangeRecord(object, "update", name, old_value); | 4342 EnqueueChangeRecord(object, "update", name, old_value); |
| 4348 } | 4343 } |
| 4349 } | 4344 } |
| 4350 } | 4345 } |
| 4351 | 4346 |
| 4352 return value; | 4347 return value; |
| 4353 } | 4348 } |
| 4354 | 4349 |
| 4355 | 4350 |
| 4356 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor( | 4351 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( |
| 4357 Handle<JSObject> object, | 4352 Handle<JSObject> holder, |
| 4358 Handle<JSObject> receiver, | 4353 Handle<Object> receiver, |
| 4359 Handle<Name> name, | 4354 Handle<Name> name) { |
| 4360 bool check_prototype) { | 4355 // TODO(rossberg): Support symbols in the API. |
| 4361 // Check own property, ignore interceptor. | 4356 if (name->IsSymbol()) return Maybe<PropertyAttributes>(ABSENT); |
| 4362 Isolate* isolate = object->GetIsolate(); | |
| 4363 LookupResult result(isolate); | |
| 4364 object->LookupOwnRealNamedProperty(name, &result); | |
| 4365 if (result.IsFound()) return result.GetAttributes(); | |
| 4366 | 4357 |
| 4367 if (check_prototype) { | 4358 Isolate* isolate = holder->GetIsolate(); |
| 4368 // Continue searching via the prototype chain. | 4359 HandleScope scope(isolate); |
| 4369 Handle<Object> proto(object->GetPrototype(), isolate); | 4360 |
| 4370 if (!proto->IsNull()) { | 4361 // Make sure that the top context does not change when doing |
| 4371 return JSReceiver::GetPropertyAttributeWithReceiver( | 4362 // callbacks or interceptor calls. |
| 4372 Handle<JSObject>::cast(proto), receiver, name); | 4363 AssertNoContextChange ncc(isolate); |
| 4364 |
| 4365 Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor()); |
| 4366 PropertyCallbackArguments args( |
| 4367 isolate, interceptor->data(), *receiver, *holder); |
| 4368 if (!interceptor->query()->IsUndefined()) { |
| 4369 v8::NamedPropertyQueryCallback query = |
| 4370 v8::ToCData<v8::NamedPropertyQueryCallback>(interceptor->query()); |
| 4371 LOG(isolate, |
| 4372 ApiNamedPropertyAccess("interceptor-named-has", *holder, *name)); |
| 4373 v8::Handle<v8::Integer> result = |
| 4374 args.Call(query, v8::Utils::ToLocal(Handle<String>::cast(name))); |
| 4375 if (!result.IsEmpty()) { |
| 4376 ASSERT(result->IsInt32()); |
| 4377 return Maybe<PropertyAttributes>( |
| 4378 static_cast<PropertyAttributes>(result->Int32Value())); |
| 4379 } |
| 4380 } else if (!interceptor->getter()->IsUndefined()) { |
| 4381 v8::NamedPropertyGetterCallback getter = |
| 4382 v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter()); |
| 4383 LOG(isolate, |
| 4384 ApiNamedPropertyAccess("interceptor-named-get-has", *holder, *name)); |
| 4385 v8::Handle<v8::Value> result = |
| 4386 args.Call(getter, v8::Utils::ToLocal(Handle<String>::cast(name))); |
| 4387 if (!result.IsEmpty()) return Maybe<PropertyAttributes>(DONT_ENUM); |
| 4388 } |
| 4389 return Maybe<PropertyAttributes>(); |
| 4390 } |
| 4391 |
| 4392 |
| 4393 PropertyAttributes JSReceiver::GetOwnPropertyAttributes( |
| 4394 Handle<JSReceiver> object, Handle<Name> name) { |
| 4395 // Check whether the name is an array index. |
| 4396 uint32_t index = 0; |
| 4397 if (object->IsJSObject() && name->AsArrayIndex(&index)) { |
| 4398 return GetOwnElementAttribute(object, index); |
| 4399 } |
| 4400 LookupIterator it(object, name, LookupIterator::CHECK_OWN); |
| 4401 return GetPropertyAttributes(&it); |
| 4402 } |
| 4403 |
| 4404 |
| 4405 PropertyAttributes JSReceiver::GetPropertyAttributes(LookupIterator* it) { |
| 4406 for (; it->IsFound(); it->Next()) { |
| 4407 switch (it->state()) { |
| 4408 case LookupIterator::NOT_FOUND: |
| 4409 UNREACHABLE(); |
| 4410 case LookupIterator::JSPROXY: |
| 4411 return JSProxy::GetPropertyAttributesWithHandler( |
| 4412 it->GetJSProxy(), it->GetReceiver(), it->name()); |
| 4413 case LookupIterator::INTERCEPTOR: { |
| 4414 Maybe<PropertyAttributes> result = |
| 4415 JSObject::GetPropertyAttributesWithInterceptor( |
| 4416 it->GetHolder(), it->GetReceiver(), it->name()); |
| 4417 if (result.has_value) return result.value; |
| 4418 break; |
| 4419 } |
| 4420 case LookupIterator::ACCESS_CHECK: |
| 4421 if (it->HasAccess(v8::ACCESS_HAS)) break; |
| 4422 return JSObject::GetPropertyAttributesWithFailedAccessCheck(it); |
| 4423 case LookupIterator::PROPERTY: |
| 4424 if (it->HasProperty()) return it->property_details().attributes(); |
| 4425 break; |
| 4373 } | 4426 } |
| 4374 } | 4427 } |
| 4375 return ABSENT; | 4428 return ABSENT; |
| 4376 } | 4429 } |
| 4377 | 4430 |
| 4378 | 4431 |
| 4379 PropertyAttributes JSObject::GetPropertyAttributeWithInterceptor( | |
| 4380 Handle<JSObject> object, | |
| 4381 Handle<JSObject> receiver, | |
| 4382 Handle<Name> name, | |
| 4383 bool check_prototype) { | |
| 4384 // TODO(rossberg): Support symbols in the API. | |
| 4385 if (name->IsSymbol()) return ABSENT; | |
| 4386 | |
| 4387 Isolate* isolate = object->GetIsolate(); | |
| 4388 HandleScope scope(isolate); | |
| 4389 | |
| 4390 // Make sure that the top context does not change when doing | |
| 4391 // callbacks or interceptor calls. | |
| 4392 AssertNoContextChange ncc(isolate); | |
| 4393 | |
| 4394 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); | |
| 4395 PropertyCallbackArguments args( | |
| 4396 isolate, interceptor->data(), *receiver, *object); | |
| 4397 if (!interceptor->query()->IsUndefined()) { | |
| 4398 v8::NamedPropertyQueryCallback query = | |
| 4399 v8::ToCData<v8::NamedPropertyQueryCallback>(interceptor->query()); | |
| 4400 LOG(isolate, | |
| 4401 ApiNamedPropertyAccess("interceptor-named-has", *object, *name)); | |
| 4402 v8::Handle<v8::Integer> result = | |
| 4403 args.Call(query, v8::Utils::ToLocal(Handle<String>::cast(name))); | |
| 4404 if (!result.IsEmpty()) { | |
| 4405 ASSERT(result->IsInt32()); | |
| 4406 return static_cast<PropertyAttributes>(result->Int32Value()); | |
| 4407 } | |
| 4408 } else if (!interceptor->getter()->IsUndefined()) { | |
| 4409 v8::NamedPropertyGetterCallback getter = | |
| 4410 v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter()); | |
| 4411 LOG(isolate, | |
| 4412 ApiNamedPropertyAccess("interceptor-named-get-has", *object, *name)); | |
| 4413 v8::Handle<v8::Value> result = | |
| 4414 args.Call(getter, v8::Utils::ToLocal(Handle<String>::cast(name))); | |
| 4415 if (!result.IsEmpty()) return DONT_ENUM; | |
| 4416 } | |
| 4417 return GetPropertyAttributePostInterceptor( | |
| 4418 object, receiver, name, check_prototype); | |
| 4419 } | |
| 4420 | |
| 4421 | |
| 4422 PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver( | |
| 4423 Handle<JSReceiver> object, | |
| 4424 Handle<JSReceiver> receiver, | |
| 4425 Handle<Name> key) { | |
| 4426 uint32_t index = 0; | |
| 4427 if (object->IsJSObject() && key->AsArrayIndex(&index)) { | |
| 4428 return JSObject::GetElementAttributeWithReceiver( | |
| 4429 Handle<JSObject>::cast(object), receiver, index, true); | |
| 4430 } | |
| 4431 // Named property. | |
| 4432 LookupResult lookup(object->GetIsolate()); | |
| 4433 object->Lookup(key, &lookup); | |
| 4434 return GetPropertyAttributeForResult(object, receiver, &lookup, key, true); | |
| 4435 } | |
| 4436 | |
| 4437 | |
| 4438 PropertyAttributes JSReceiver::GetPropertyAttributeForResult( | |
| 4439 Handle<JSReceiver> object, | |
| 4440 Handle<JSReceiver> receiver, | |
| 4441 LookupResult* lookup, | |
| 4442 Handle<Name> name, | |
| 4443 bool check_prototype) { | |
| 4444 // Check access rights if needed. | |
| 4445 if (object->IsAccessCheckNeeded()) { | |
| 4446 Heap* heap = object->GetHeap(); | |
| 4447 Handle<JSObject> obj = Handle<JSObject>::cast(object); | |
| 4448 if (!heap->isolate()->MayNamedAccess(obj, name, v8::ACCESS_HAS)) { | |
| 4449 return JSObject::GetPropertyAttributeWithFailedAccessCheck( | |
| 4450 obj, lookup, name, check_prototype); | |
| 4451 } | |
| 4452 } | |
| 4453 if (lookup->IsFound()) { | |
| 4454 switch (lookup->type()) { | |
| 4455 case NORMAL: // fall through | |
| 4456 case FIELD: | |
| 4457 case CONSTANT: | |
| 4458 case CALLBACKS: | |
| 4459 return lookup->GetAttributes(); | |
| 4460 case HANDLER: { | |
| 4461 return JSProxy::GetPropertyAttributeWithHandler( | |
| 4462 handle(lookup->proxy()), receiver, name); | |
| 4463 } | |
| 4464 case INTERCEPTOR: | |
| 4465 return JSObject::GetPropertyAttributeWithInterceptor( | |
| 4466 handle(lookup->holder()), | |
| 4467 Handle<JSObject>::cast(receiver), | |
| 4468 name, | |
| 4469 check_prototype); | |
| 4470 case NONEXISTENT: | |
| 4471 UNREACHABLE(); | |
| 4472 } | |
| 4473 } | |
| 4474 return ABSENT; | |
| 4475 } | |
| 4476 | |
| 4477 | |
| 4478 PropertyAttributes JSReceiver::GetOwnPropertyAttribute( | |
| 4479 Handle<JSReceiver> object, Handle<Name> name) { | |
| 4480 // Check whether the name is an array index. | |
| 4481 uint32_t index = 0; | |
| 4482 if (object->IsJSObject() && name->AsArrayIndex(&index)) { | |
| 4483 return GetOwnElementAttribute(object, index); | |
| 4484 } | |
| 4485 // Named property. | |
| 4486 LookupResult lookup(object->GetIsolate()); | |
| 4487 object->LookupOwn(name, &lookup, true); | |
| 4488 return GetPropertyAttributeForResult(object, object, &lookup, name, false); | |
| 4489 } | |
| 4490 | |
| 4491 | |
| 4492 PropertyAttributes JSObject::GetElementAttributeWithReceiver( | 4432 PropertyAttributes JSObject::GetElementAttributeWithReceiver( |
| 4493 Handle<JSObject> object, | 4433 Handle<JSObject> object, |
| 4494 Handle<JSReceiver> receiver, | 4434 Handle<JSReceiver> receiver, |
| 4495 uint32_t index, | 4435 uint32_t index, |
| 4496 bool check_prototype) { | 4436 bool check_prototype) { |
| 4497 Isolate* isolate = object->GetIsolate(); | 4437 Isolate* isolate = object->GetIsolate(); |
| 4498 | 4438 |
| 4499 // Check access rights if needed. | 4439 // Check access rights if needed. |
| 4500 if (object->IsAccessCheckNeeded()) { | 4440 if (object->IsAccessCheckNeeded()) { |
| 4501 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) { | 4441 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) { |
| (...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5155 if (inline_value->IsUndefined() || inline_value->IsSmi()) return; | 5095 if (inline_value->IsUndefined() || inline_value->IsSmi()) return; |
| 5156 | 5096 |
| 5157 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); | 5097 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); |
| 5158 bool was_present = false; | 5098 bool was_present = false; |
| 5159 ObjectHashTable::Remove(hashtable, key, &was_present); | 5099 ObjectHashTable::Remove(hashtable, key, &was_present); |
| 5160 } | 5100 } |
| 5161 | 5101 |
| 5162 | 5102 |
| 5163 bool JSObject::HasHiddenProperties(Handle<JSObject> object) { | 5103 bool JSObject::HasHiddenProperties(Handle<JSObject> object) { |
| 5164 Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string(); | 5104 Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string(); |
| 5165 return GetPropertyAttributePostInterceptor( | 5105 LookupIterator it(object, hidden, LookupIterator::CHECK_OWN_REAL); |
| 5166 object, object, hidden, false) != ABSENT; | 5106 return GetPropertyAttributes(&it) != ABSENT; |
| 5167 } | 5107 } |
| 5168 | 5108 |
| 5169 | 5109 |
| 5170 Object* JSObject::GetHiddenPropertiesHashTable() { | 5110 Object* JSObject::GetHiddenPropertiesHashTable() { |
| 5171 ASSERT(!IsJSGlobalProxy()); | 5111 ASSERT(!IsJSGlobalProxy()); |
| 5172 if (HasFastProperties()) { | 5112 if (HasFastProperties()) { |
| 5173 // If the object has fast properties, check whether the first slot | 5113 // If the object has fast properties, check whether the first slot |
| 5174 // in the descriptor array matches the hidden string. Since the | 5114 // in the descriptor array matches the hidden string. Since the |
| 5175 // hidden strings hash code is zero (and no other name has hash | 5115 // hidden strings hash code is zero (and no other name has hash |
| 5176 // code zero) it will always occupy the first entry if present. | 5116 // code zero) it will always occupy the first entry if present. |
| (...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5971 } | 5911 } |
| 5972 } | 5912 } |
| 5973 } else { | 5913 } else { |
| 5974 Handle<FixedArray> names = | 5914 Handle<FixedArray> names = |
| 5975 isolate->factory()->NewFixedArray(copy->NumberOfOwnProperties()); | 5915 isolate->factory()->NewFixedArray(copy->NumberOfOwnProperties()); |
| 5976 copy->GetOwnPropertyNames(*names, 0); | 5916 copy->GetOwnPropertyNames(*names, 0); |
| 5977 for (int i = 0; i < names->length(); i++) { | 5917 for (int i = 0; i < names->length(); i++) { |
| 5978 ASSERT(names->get(i)->IsString()); | 5918 ASSERT(names->get(i)->IsString()); |
| 5979 Handle<String> key_string(String::cast(names->get(i))); | 5919 Handle<String> key_string(String::cast(names->get(i))); |
| 5980 PropertyAttributes attributes = | 5920 PropertyAttributes attributes = |
| 5981 JSReceiver::GetOwnPropertyAttribute(copy, key_string); | 5921 JSReceiver::GetOwnPropertyAttributes(copy, key_string); |
| 5982 // Only deep copy fields from the object literal expression. | 5922 // Only deep copy fields from the object literal expression. |
| 5983 // In particular, don't try to copy the length attribute of | 5923 // In particular, don't try to copy the length attribute of |
| 5984 // an array. | 5924 // an array. |
| 5985 if (attributes != NONE) continue; | 5925 if (attributes != NONE) continue; |
| 5986 Handle<Object> value = | 5926 Handle<Object> value = |
| 5987 Object::GetProperty(copy, key_string).ToHandleChecked(); | 5927 Object::GetProperty(copy, key_string).ToHandleChecked(); |
| 5988 if (value->IsJSObject()) { | 5928 if (value->IsJSObject()) { |
| 5989 Handle<JSObject> result; | 5929 Handle<JSObject> result; |
| 5990 ASSIGN_RETURN_ON_EXCEPTION( | 5930 ASSIGN_RETURN_ON_EXCEPTION( |
| 5991 isolate, result, | 5931 isolate, result, |
| (...skipping 11116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17108 #define ERROR_MESSAGES_TEXTS(C, T) T, | 17048 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 17109 static const char* error_messages_[] = { | 17049 static const char* error_messages_[] = { |
| 17110 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 17050 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 17111 }; | 17051 }; |
| 17112 #undef ERROR_MESSAGES_TEXTS | 17052 #undef ERROR_MESSAGES_TEXTS |
| 17113 return error_messages_[reason]; | 17053 return error_messages_[reason]; |
| 17114 } | 17054 } |
| 17115 | 17055 |
| 17116 | 17056 |
| 17117 } } // namespace v8::internal | 17057 } } // namespace v8::internal |
| OLD | NEW |