| 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 <iomanip> | 5 #include <iomanip> |
| 6 #include <sstream> | 6 #include <sstream> |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 } | 126 } |
| 127 | 127 |
| 128 | 128 |
| 129 MaybeHandle<Object> Object::GetProperty(LookupIterator* it) { | 129 MaybeHandle<Object> Object::GetProperty(LookupIterator* it) { |
| 130 for (; it->IsFound(); it->Next()) { | 130 for (; it->IsFound(); it->Next()) { |
| 131 switch (it->state()) { | 131 switch (it->state()) { |
| 132 case LookupIterator::NOT_FOUND: | 132 case LookupIterator::NOT_FOUND: |
| 133 case LookupIterator::TRANSITION: | 133 case LookupIterator::TRANSITION: |
| 134 UNREACHABLE(); | 134 UNREACHABLE(); |
| 135 case LookupIterator::JSPROXY: | 135 case LookupIterator::JSPROXY: |
| 136 return JSProxy::GetPropertyWithHandler(it->GetHolder<JSProxy>(), | 136 return JSProxy::GetPropertyWithHandler( |
| 137 it->GetReceiver(), it->name()); | 137 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName()); |
| 138 case LookupIterator::INTERCEPTOR: { | 138 case LookupIterator::INTERCEPTOR: { |
| 139 MaybeHandle<Object> maybe_result = | 139 MaybeHandle<Object> maybe_result = |
| 140 JSObject::GetPropertyWithInterceptor(it); | 140 JSObject::GetPropertyWithInterceptor(it); |
| 141 if (!maybe_result.is_null()) return maybe_result; | 141 if (!maybe_result.is_null()) return maybe_result; |
| 142 if (it->isolate()->has_pending_exception()) return maybe_result; | 142 if (it->isolate()->has_pending_exception()) return maybe_result; |
| 143 break; | 143 break; |
| 144 } | 144 } |
| 145 case LookupIterator::ACCESS_CHECK: | 145 case LookupIterator::ACCESS_CHECK: |
| 146 if (it->HasAccess()) break; | 146 if (it->HasAccess()) break; |
| 147 return JSObject::GetPropertyWithFailedAccessCheck(it); | 147 return JSObject::GetPropertyWithFailedAccessCheck(it); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 | 303 |
| 304 MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) { | 304 MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) { |
| 305 Isolate* isolate = it->isolate(); | 305 Isolate* isolate = it->isolate(); |
| 306 Handle<Object> structure = it->GetAccessors(); | 306 Handle<Object> structure = it->GetAccessors(); |
| 307 Handle<Object> receiver = it->GetReceiver(); | 307 Handle<Object> receiver = it->GetReceiver(); |
| 308 | 308 |
| 309 DCHECK(!structure->IsForeign()); | 309 DCHECK(!structure->IsForeign()); |
| 310 // api style callbacks. | 310 // api style callbacks. |
| 311 if (structure->IsAccessorInfo()) { | 311 if (structure->IsAccessorInfo()) { |
| 312 Handle<JSObject> holder = it->GetHolder<JSObject>(); | 312 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 313 Handle<Name> name = it->name(); | 313 Handle<Name> name = it->GetName(); |
| 314 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure); | 314 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure); |
| 315 if (!info->IsCompatibleReceiver(*receiver)) { | 315 if (!info->IsCompatibleReceiver(*receiver)) { |
| 316 THROW_NEW_ERROR(isolate, | 316 THROW_NEW_ERROR(isolate, |
| 317 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, | 317 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, |
| 318 name, receiver), | 318 name, receiver), |
| 319 Object); | 319 Object); |
| 320 } | 320 } |
| 321 | 321 |
| 322 Handle<ExecutableAccessorInfo> data = | 322 Handle<ExecutableAccessorInfo> data = |
| 323 Handle<ExecutableAccessorInfo>::cast(structure); | 323 Handle<ExecutableAccessorInfo>::cast(structure); |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 | 504 |
| 505 | 505 |
| 506 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck( | 506 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck( |
| 507 LookupIterator* it) { | 507 LookupIterator* it) { |
| 508 Handle<JSObject> checked = it->GetHolder<JSObject>(); | 508 Handle<JSObject> checked = it->GetHolder<JSObject>(); |
| 509 while (FindAllCanReadHolder(it)) { | 509 while (FindAllCanReadHolder(it)) { |
| 510 if (it->state() == LookupIterator::ACCESSOR) { | 510 if (it->state() == LookupIterator::ACCESSOR) { |
| 511 return Just(it->property_details().attributes()); | 511 return Just(it->property_details().attributes()); |
| 512 } | 512 } |
| 513 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); | 513 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
| 514 auto result = GetPropertyAttributesWithInterceptor( | 514 auto result = GetPropertyAttributesWithInterceptor(it); |
| 515 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); | |
| 516 if (it->isolate()->has_scheduled_exception()) break; | 515 if (it->isolate()->has_scheduled_exception()) break; |
| 517 if (result.IsJust() && result.FromJust() != ABSENT) return result; | 516 if (result.IsJust() && result.FromJust() != ABSENT) return result; |
| 518 } | 517 } |
| 519 it->isolate()->ReportFailedAccessCheck(checked); | 518 it->isolate()->ReportFailedAccessCheck(checked); |
| 520 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), | 519 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), |
| 521 Nothing<PropertyAttributes>()); | 520 Nothing<PropertyAttributes>()); |
| 522 return Just(ABSENT); | 521 return Just(ABSENT); |
| 523 } | 522 } |
| 524 | 523 |
| 525 | 524 |
| 526 static bool FindAllCanWriteHolder(LookupIterator* it) { | 525 static bool FindAllCanWriteHolder(LookupIterator* it) { |
| 527 for (; it->IsFound(); it->Next()) { | 526 for (; it->IsFound(); it->Next()) { |
| 528 if (it->state() == LookupIterator::ACCESSOR) { | 527 if (it->state() == LookupIterator::ACCESSOR) { |
| 529 Handle<Object> accessors = it->GetAccessors(); | 528 Handle<Object> accessors = it->GetAccessors(); |
| 530 if (accessors->IsAccessorInfo()) { | 529 if (accessors->IsAccessorInfo()) { |
| 531 if (AccessorInfo::cast(*accessors)->all_can_write()) return true; | 530 if (AccessorInfo::cast(*accessors)->all_can_write()) return true; |
| 532 } | 531 } |
| 533 } | 532 } |
| 534 } | 533 } |
| 535 return false; | 534 return false; |
| 536 } | 535 } |
| 537 | 536 |
| 538 | 537 |
| 539 MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck( | 538 MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck( |
| 540 LookupIterator* it, Handle<Object> value, LanguageMode language_mode) { | 539 LookupIterator* it, Handle<Object> value, LanguageMode language_mode) { |
| 541 Handle<JSObject> checked = it->GetHolder<JSObject>(); | 540 Handle<JSObject> checked = it->GetHolder<JSObject>(); |
| 542 if (FindAllCanWriteHolder(it)) { | 541 if (FindAllCanWriteHolder(it)) { |
| 543 return SetPropertyWithAccessor(it->GetReceiver(), it->name(), value, | 542 return SetPropertyWithAccessor(it->GetReceiver(), it->GetName(), value, |
| 544 it->GetHolder<JSObject>(), | 543 it->GetHolder<JSObject>(), |
| 545 it->GetAccessors(), language_mode); | 544 it->GetAccessors(), language_mode); |
| 546 } | 545 } |
| 547 | 546 |
| 548 it->isolate()->ReportFailedAccessCheck(checked); | 547 it->isolate()->ReportFailedAccessCheck(checked); |
| 549 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); | 548 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); |
| 550 return value; | 549 return value; |
| 551 } | 550 } |
| 552 | 551 |
| 553 | 552 |
| (...skipping 2612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3166 case LookupIterator::ACCESS_CHECK: | 3165 case LookupIterator::ACCESS_CHECK: |
| 3167 // TODO(verwaest): Remove the distinction. This is mostly bogus since we | 3166 // TODO(verwaest): Remove the distinction. This is mostly bogus since we |
| 3168 // don't know whether we'll want to fetch attributes or call a setter | 3167 // don't know whether we'll want to fetch attributes or call a setter |
| 3169 // until we find the property. | 3168 // until we find the property. |
| 3170 if (it->HasAccess()) break; | 3169 if (it->HasAccess()) break; |
| 3171 return JSObject::SetPropertyWithFailedAccessCheck(it, value, | 3170 return JSObject::SetPropertyWithFailedAccessCheck(it, value, |
| 3172 language_mode); | 3171 language_mode); |
| 3173 | 3172 |
| 3174 case LookupIterator::JSPROXY: | 3173 case LookupIterator::JSPROXY: |
| 3175 if (it->HolderIsReceiverOrHiddenPrototype()) { | 3174 if (it->HolderIsReceiverOrHiddenPrototype()) { |
| 3176 return JSProxy::SetPropertyWithHandler(it->GetHolder<JSProxy>(), | 3175 return JSProxy::SetPropertyWithHandler( |
| 3177 it->GetReceiver(), it->name(), | 3176 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(), value, |
| 3178 value, language_mode); | 3177 language_mode); |
| 3179 } else { | 3178 } else { |
| 3180 // TODO(verwaest): Use the MaybeHandle to indicate result. | 3179 // TODO(verwaest): Use the MaybeHandle to indicate result. |
| 3181 bool has_result = false; | 3180 bool has_result = false; |
| 3182 MaybeHandle<Object> maybe_result = | 3181 MaybeHandle<Object> maybe_result = |
| 3183 JSProxy::SetPropertyViaPrototypesWithHandler( | 3182 JSProxy::SetPropertyViaPrototypesWithHandler( |
| 3184 it->GetHolder<JSProxy>(), it->GetReceiver(), it->name(), | 3183 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(), |
| 3185 value, language_mode, &has_result); | 3184 value, language_mode, &has_result); |
| 3186 if (has_result) return maybe_result; | 3185 if (has_result) return maybe_result; |
| 3187 done = true; | 3186 done = true; |
| 3188 } | 3187 } |
| 3189 break; | 3188 break; |
| 3190 | 3189 |
| 3191 case LookupIterator::INTERCEPTOR: | 3190 case LookupIterator::INTERCEPTOR: |
| 3192 if (it->HolderIsReceiverOrHiddenPrototype()) { | 3191 if (it->HolderIsReceiverOrHiddenPrototype()) { |
| 3193 MaybeHandle<Object> maybe_result = | 3192 MaybeHandle<Object> maybe_result = |
| 3194 JSObject::SetPropertyWithInterceptor(it, value); | 3193 JSObject::SetPropertyWithInterceptor(it, value); |
| 3195 if (!maybe_result.is_null()) return maybe_result; | 3194 if (!maybe_result.is_null()) return maybe_result; |
| 3196 if (it->isolate()->has_pending_exception()) return maybe_result; | 3195 if (it->isolate()->has_pending_exception()) return maybe_result; |
| 3197 } else { | 3196 } else { |
| 3198 Maybe<PropertyAttributes> maybe_attributes = | 3197 Maybe<PropertyAttributes> maybe_attributes = |
| 3199 JSObject::GetPropertyAttributesWithInterceptor( | 3198 JSObject::GetPropertyAttributesWithInterceptor(it); |
| 3200 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); | |
| 3201 if (!maybe_attributes.IsJust()) return MaybeHandle<Object>(); | 3199 if (!maybe_attributes.IsJust()) return MaybeHandle<Object>(); |
| 3202 done = maybe_attributes.FromJust() != ABSENT; | 3200 done = maybe_attributes.FromJust() != ABSENT; |
| 3203 if (done && (maybe_attributes.FromJust() & READ_ONLY) != 0) { | 3201 if (done && (maybe_attributes.FromJust() & READ_ONLY) != 0) { |
| 3204 return WriteToReadOnlyProperty(it, value, language_mode); | 3202 return WriteToReadOnlyProperty(it, value, language_mode); |
| 3205 } | 3203 } |
| 3206 } | 3204 } |
| 3207 break; | 3205 break; |
| 3208 | 3206 |
| 3209 case LookupIterator::ACCESSOR: { | 3207 case LookupIterator::ACCESSOR: { |
| 3210 if (it->property_details().IsReadOnly()) { | 3208 if (it->property_details().IsReadOnly()) { |
| 3211 return WriteToReadOnlyProperty(it, value, language_mode); | 3209 return WriteToReadOnlyProperty(it, value, language_mode); |
| 3212 } | 3210 } |
| 3213 Handle<Object> accessors = it->GetAccessors(); | 3211 Handle<Object> accessors = it->GetAccessors(); |
| 3214 if (accessors->IsAccessorInfo() && | 3212 if (accessors->IsAccessorInfo() && |
| 3215 !it->HolderIsReceiverOrHiddenPrototype() && | 3213 !it->HolderIsReceiverOrHiddenPrototype() && |
| 3216 AccessorInfo::cast(*accessors)->is_special_data_property()) { | 3214 AccessorInfo::cast(*accessors)->is_special_data_property()) { |
| 3217 done = true; | 3215 done = true; |
| 3218 break; | 3216 break; |
| 3219 } | 3217 } |
| 3220 return SetPropertyWithAccessor(it->GetReceiver(), it->name(), value, | 3218 return SetPropertyWithAccessor(it->GetReceiver(), it->GetName(), value, |
| 3221 it->GetHolder<JSObject>(), accessors, | 3219 it->GetHolder<JSObject>(), accessors, |
| 3222 language_mode); | 3220 language_mode); |
| 3223 } | 3221 } |
| 3224 case LookupIterator::INTEGER_INDEXED_EXOTIC: | 3222 case LookupIterator::INTEGER_INDEXED_EXOTIC: |
| 3225 done = true; | 3223 done = true; |
| 3226 break; | 3224 break; |
| 3227 | 3225 |
| 3228 case LookupIterator::DATA: | 3226 case LookupIterator::DATA: |
| 3229 if (it->property_details().IsReadOnly()) { | 3227 if (it->property_details().IsReadOnly()) { |
| 3230 return WriteToReadOnlyProperty(it, value, language_mode); | 3228 return WriteToReadOnlyProperty(it, value, language_mode); |
| (...skipping 1121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4352 } | 4350 } |
| 4353 } | 4351 } |
| 4354 } | 4352 } |
| 4355 | 4353 |
| 4356 return AddDataProperty(&it, value, attributes, STRICT, | 4354 return AddDataProperty(&it, value, attributes, STRICT, |
| 4357 CERTAINLY_NOT_STORE_FROM_KEYED); | 4355 CERTAINLY_NOT_STORE_FROM_KEYED); |
| 4358 } | 4356 } |
| 4359 | 4357 |
| 4360 | 4358 |
| 4361 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( | 4359 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor( |
| 4362 Handle<JSObject> holder, | 4360 LookupIterator* it) { |
| 4363 Handle<Object> receiver, | 4361 Isolate* isolate = it->isolate(); |
| 4364 Handle<Name> name) { | |
| 4365 Isolate* isolate = holder->GetIsolate(); | |
| 4366 HandleScope scope(isolate); | |
| 4367 | |
| 4368 // Make sure that the top context does not change when doing | 4362 // Make sure that the top context does not change when doing |
| 4369 // callbacks or interceptor calls. | 4363 // callbacks or interceptor calls. |
| 4370 AssertNoContextChange ncc(isolate); | 4364 AssertNoContextChange ncc(isolate); |
| 4365 HandleScope scope(isolate); |
| 4371 | 4366 |
| 4372 Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor()); | 4367 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 4373 if (name->IsSymbol() && !interceptor->can_intercept_symbols()) { | 4368 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); |
| 4369 if (!it->IsElement() && it->name()->IsSymbol() && |
| 4370 !interceptor->can_intercept_symbols()) { |
| 4374 return Just(ABSENT); | 4371 return Just(ABSENT); |
| 4375 } | 4372 } |
| 4376 PropertyCallbackArguments args( | 4373 PropertyCallbackArguments args(isolate, interceptor->data(), |
| 4377 isolate, interceptor->data(), *receiver, *holder); | 4374 *it->GetReceiver(), *holder); |
| 4378 if (!interceptor->query()->IsUndefined()) { | 4375 if (!interceptor->query()->IsUndefined()) { |
| 4379 v8::GenericNamedPropertyQueryCallback query = | 4376 v8::Handle<v8::Integer> result; |
| 4380 v8::ToCData<v8::GenericNamedPropertyQueryCallback>( | 4377 if (it->IsElement()) { |
| 4381 interceptor->query()); | 4378 uint32_t index = it->index(); |
| 4382 LOG(isolate, | 4379 v8::IndexedPropertyQueryCallback query = |
| 4383 ApiNamedPropertyAccess("interceptor-named-has", *holder, *name)); | 4380 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query()); |
| 4384 v8::Handle<v8::Integer> result = args.Call(query, v8::Utils::ToLocal(name)); | 4381 LOG(isolate, |
| 4382 ApiIndexedPropertyAccess("interceptor-indexed-has", *holder, index)); |
| 4383 result = args.Call(query, index); |
| 4384 } else { |
| 4385 Handle<Name> name = it->name(); |
| 4386 v8::GenericNamedPropertyQueryCallback query = |
| 4387 v8::ToCData<v8::GenericNamedPropertyQueryCallback>( |
| 4388 interceptor->query()); |
| 4389 LOG(isolate, |
| 4390 ApiNamedPropertyAccess("interceptor-named-has", *holder, *name)); |
| 4391 result = args.Call(query, v8::Utils::ToLocal(name)); |
| 4392 } |
| 4385 if (!result.IsEmpty()) { | 4393 if (!result.IsEmpty()) { |
| 4386 DCHECK(result->IsInt32()); | 4394 DCHECK(result->IsInt32()); |
| 4387 return Just(static_cast<PropertyAttributes>(result->Int32Value())); | 4395 return Just(static_cast<PropertyAttributes>(result->Int32Value())); |
| 4388 } | 4396 } |
| 4389 } else if (!interceptor->getter()->IsUndefined()) { | 4397 } else if (!interceptor->getter()->IsUndefined()) { |
| 4390 v8::GenericNamedPropertyGetterCallback getter = | 4398 // TODO(verwaest): Use GetPropertyWithInterceptor? |
| 4391 v8::ToCData<v8::GenericNamedPropertyGetterCallback>( | 4399 v8::Handle<v8::Value> result; |
| 4392 interceptor->getter()); | 4400 if (it->IsElement()) { |
| 4393 LOG(isolate, | 4401 uint32_t index = it->index(); |
| 4394 ApiNamedPropertyAccess("interceptor-named-get-has", *holder, *name)); | 4402 v8::IndexedPropertyGetterCallback getter = |
| 4395 v8::Handle<v8::Value> result = args.Call(getter, v8::Utils::ToLocal(name)); | 4403 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); |
| 4404 LOG(isolate, ApiIndexedPropertyAccess("interceptor-indexed-get-has", |
| 4405 *holder, index)); |
| 4406 result = args.Call(getter, index); |
| 4407 } else { |
| 4408 Handle<Name> name = it->name(); |
| 4409 |
| 4410 v8::GenericNamedPropertyGetterCallback getter = |
| 4411 v8::ToCData<v8::GenericNamedPropertyGetterCallback>( |
| 4412 interceptor->getter()); |
| 4413 LOG(isolate, |
| 4414 ApiNamedPropertyAccess("interceptor-named-get-has", *holder, *name)); |
| 4415 result = args.Call(getter, v8::Utils::ToLocal(name)); |
| 4416 } |
| 4396 if (!result.IsEmpty()) return Just(DONT_ENUM); | 4417 if (!result.IsEmpty()) return Just(DONT_ENUM); |
| 4397 } | 4418 } |
| 4398 | 4419 |
| 4399 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>()); | 4420 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>()); |
| 4400 return Just(ABSENT); | 4421 return Just(ABSENT); |
| 4401 } | 4422 } |
| 4402 | 4423 |
| 4403 | 4424 |
| 4404 Maybe<PropertyAttributes> JSReceiver::GetOwnPropertyAttributes( | 4425 Maybe<PropertyAttributes> JSReceiver::GetOwnPropertyAttributes( |
| 4405 Handle<JSReceiver> object, Handle<Name> name) { | 4426 Handle<JSReceiver> object, Handle<Name> name) { |
| 4406 // Check whether the name is an array index. | 4427 // Check whether the name is an array index. |
| 4407 uint32_t index = 0; | 4428 uint32_t index = 0; |
| 4408 if (object->IsJSObject() && name->AsArrayIndex(&index)) { | 4429 if (object->IsJSObject() && name->AsArrayIndex(&index)) { |
| 4409 return GetOwnElementAttribute(object, index); | 4430 return GetOwnElementAttribute(object, index); |
| 4410 } | 4431 } |
| 4411 LookupIterator it(object, name, LookupIterator::HIDDEN); | 4432 LookupIterator it(object, name, LookupIterator::HIDDEN); |
| 4412 return GetPropertyAttributes(&it); | 4433 return GetPropertyAttributes(&it); |
| 4413 } | 4434 } |
| 4414 | 4435 |
| 4415 | 4436 |
| 4416 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes( | 4437 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes( |
| 4417 LookupIterator* it) { | 4438 LookupIterator* it) { |
| 4418 for (; it->IsFound(); it->Next()) { | 4439 for (; it->IsFound(); it->Next()) { |
| 4419 switch (it->state()) { | 4440 switch (it->state()) { |
| 4420 case LookupIterator::NOT_FOUND: | 4441 case LookupIterator::NOT_FOUND: |
| 4421 case LookupIterator::TRANSITION: | 4442 case LookupIterator::TRANSITION: |
| 4422 UNREACHABLE(); | 4443 UNREACHABLE(); |
| 4423 case LookupIterator::JSPROXY: | 4444 case LookupIterator::JSPROXY: |
| 4424 return JSProxy::GetPropertyAttributesWithHandler( | 4445 return JSProxy::GetPropertyAttributesWithHandler( |
| 4425 it->GetHolder<JSProxy>(), it->GetReceiver(), it->name()); | 4446 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName()); |
| 4426 case LookupIterator::INTERCEPTOR: { | 4447 case LookupIterator::INTERCEPTOR: { |
| 4427 Maybe<PropertyAttributes> result = | 4448 Maybe<PropertyAttributes> result = |
| 4428 JSObject::GetPropertyAttributesWithInterceptor( | 4449 JSObject::GetPropertyAttributesWithInterceptor(it); |
| 4429 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); | |
| 4430 if (!result.IsJust()) return result; | 4450 if (!result.IsJust()) return result; |
| 4431 if (result.FromJust() != ABSENT) return result; | 4451 if (result.FromJust() != ABSENT) return result; |
| 4432 break; | 4452 break; |
| 4433 } | 4453 } |
| 4434 case LookupIterator::ACCESS_CHECK: | 4454 case LookupIterator::ACCESS_CHECK: |
| 4435 if (it->HasAccess()) break; | 4455 if (it->HasAccess()) break; |
| 4436 return JSObject::GetPropertyAttributesWithFailedAccessCheck(it); | 4456 return JSObject::GetPropertyAttributesWithFailedAccessCheck(it); |
| 4437 case LookupIterator::INTEGER_INDEXED_EXOTIC: | 4457 case LookupIterator::INTEGER_INDEXED_EXOTIC: |
| 4438 return Just(ABSENT); | 4458 return Just(ABSENT); |
| 4439 case LookupIterator::ACCESSOR: | 4459 case LookupIterator::ACCESSOR: |
| (...skipping 9577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14017 DCHECK(map()->has_indexed_interceptor()); | 14037 DCHECK(map()->has_indexed_interceptor()); |
| 14018 JSFunction* constructor = JSFunction::cast(map()->GetConstructor()); | 14038 JSFunction* constructor = JSFunction::cast(map()->GetConstructor()); |
| 14019 DCHECK(constructor->shared()->IsApiFunction()); | 14039 DCHECK(constructor->shared()->IsApiFunction()); |
| 14020 Object* result = | 14040 Object* result = |
| 14021 constructor->shared()->get_api_func_data()->indexed_property_handler(); | 14041 constructor->shared()->get_api_func_data()->indexed_property_handler(); |
| 14022 return InterceptorInfo::cast(result); | 14042 return InterceptorInfo::cast(result); |
| 14023 } | 14043 } |
| 14024 | 14044 |
| 14025 | 14045 |
| 14026 MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it) { | 14046 MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it) { |
| 14047 Isolate* isolate = it->isolate(); |
| 14048 // Make sure that the top context does not change when doing callbacks or |
| 14049 // interceptor calls. |
| 14050 AssertNoContextChange ncc(isolate); |
| 14051 |
| 14027 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); | 14052 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
| 14028 Isolate* isolate = it->isolate(); | |
| 14029 Handle<InterceptorInfo> interceptor = it->GetInterceptor(); | 14053 Handle<InterceptorInfo> interceptor = it->GetInterceptor(); |
| 14030 if (interceptor->getter()->IsUndefined()) return MaybeHandle<Object>(); | 14054 if (interceptor->getter()->IsUndefined()) return MaybeHandle<Object>(); |
| 14031 | 14055 |
| 14032 Handle<Name> name = it->name(); | |
| 14033 Handle<JSObject> holder = it->GetHolder<JSObject>(); | 14056 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 14057 v8::Handle<v8::Value> result; |
| 14058 PropertyCallbackArguments args(isolate, interceptor->data(), |
| 14059 *it->GetReceiver(), *holder); |
| 14034 | 14060 |
| 14035 if (name->IsSymbol() && !interceptor->can_intercept_symbols()) { | 14061 if (it->IsElement()) { |
| 14036 return MaybeHandle<Object>(); | 14062 uint32_t index = it->index(); |
| 14063 v8::IndexedPropertyGetterCallback getter = |
| 14064 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); |
| 14065 LOG(isolate, |
| 14066 ApiIndexedPropertyAccess("interceptor-indexed-get", *holder, index)); |
| 14067 result = args.Call(getter, index); |
| 14068 } else { |
| 14069 Handle<Name> name = it->name(); |
| 14070 |
| 14071 if (name->IsSymbol() && !interceptor->can_intercept_symbols()) { |
| 14072 return MaybeHandle<Object>(); |
| 14073 } |
| 14074 |
| 14075 v8::GenericNamedPropertyGetterCallback getter = |
| 14076 v8::ToCData<v8::GenericNamedPropertyGetterCallback>( |
| 14077 interceptor->getter()); |
| 14078 LOG(isolate, |
| 14079 ApiNamedPropertyAccess("interceptor-named-get", *holder, *name)); |
| 14080 result = args.Call(getter, v8::Utils::ToLocal(name)); |
| 14037 } | 14081 } |
| 14038 | 14082 |
| 14039 v8::GenericNamedPropertyGetterCallback getter = | |
| 14040 v8::ToCData<v8::GenericNamedPropertyGetterCallback>( | |
| 14041 interceptor->getter()); | |
| 14042 LOG(isolate, | |
| 14043 ApiNamedPropertyAccess("interceptor-named-get", *holder, *name)); | |
| 14044 PropertyCallbackArguments args(isolate, interceptor->data(), | |
| 14045 *it->GetReceiver(), *holder); | |
| 14046 v8::Handle<v8::Value> result = args.Call(getter, v8::Utils::ToLocal(name)); | |
| 14047 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 14083 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 14048 if (result.IsEmpty()) return MaybeHandle<Object>(); | 14084 if (result.IsEmpty()) return MaybeHandle<Object>(); |
| 14049 | |
| 14050 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); | 14085 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); |
| 14051 result_internal->VerifyApiCallResultType(); | 14086 result_internal->VerifyApiCallResultType(); |
| 14052 // Rebox handle before return | 14087 // Rebox handle before return |
| 14053 return handle(*result_internal, isolate); | 14088 return handle(*result_internal, isolate); |
| 14054 } | 14089 } |
| 14055 | 14090 |
| 14056 | 14091 |
| 14057 // Compute the property keys from the interceptor. | 14092 // Compute the property keys from the interceptor. |
| 14058 MaybeHandle<JSObject> JSObject::GetKeysForNamedInterceptor( | 14093 MaybeHandle<JSObject> JSObject::GetKeysForNamedInterceptor( |
| 14059 Handle<JSObject> object, Handle<JSReceiver> receiver) { | 14094 Handle<JSObject> object, Handle<JSReceiver> receiver) { |
| (...skipping 3230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17290 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, | 17325 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, |
| 17291 Handle<Object> new_value) { | 17326 Handle<Object> new_value) { |
| 17292 if (cell->value() != *new_value) { | 17327 if (cell->value() != *new_value) { |
| 17293 cell->set_value(*new_value); | 17328 cell->set_value(*new_value); |
| 17294 Isolate* isolate = cell->GetIsolate(); | 17329 Isolate* isolate = cell->GetIsolate(); |
| 17295 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17330 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 17296 isolate, DependentCode::kPropertyCellChangedGroup); | 17331 isolate, DependentCode::kPropertyCellChangedGroup); |
| 17297 } | 17332 } |
| 17298 } | 17333 } |
| 17299 } } // namespace v8::internal | 17334 } } // namespace v8::internal |
| OLD | NEW |