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