| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| (...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1049 THROW_NEW_ERROR(isolate, | 1049 THROW_NEW_ERROR(isolate, |
| 1050 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, | 1050 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, |
| 1051 name, receiver), | 1051 name, receiver), |
| 1052 Object); | 1052 Object); |
| 1053 } | 1053 } |
| 1054 | 1054 |
| 1055 v8::AccessorNameGetterCallback call_fun = | 1055 v8::AccessorNameGetterCallback call_fun = |
| 1056 v8::ToCData<v8::AccessorNameGetterCallback>(info->getter()); | 1056 v8::ToCData<v8::AccessorNameGetterCallback>(info->getter()); |
| 1057 if (call_fun == nullptr) return isolate->factory()->undefined_value(); | 1057 if (call_fun == nullptr) return isolate->factory()->undefined_value(); |
| 1058 | 1058 |
| 1059 LOG(isolate, ApiNamedPropertyAccess("load", *holder, *name)); | |
| 1060 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder, | 1059 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder, |
| 1061 Object::DONT_THROW); | 1060 Object::DONT_THROW); |
| 1062 v8::Local<v8::Value> result = args.Call(call_fun, v8::Utils::ToLocal(name)); | 1061 Handle<Object> result = args.Call(call_fun, name); |
| 1063 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 1062 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 1064 if (result.IsEmpty()) { | 1063 if (result.is_null()) return ReadAbsentProperty(isolate, receiver, name); |
| 1065 return ReadAbsentProperty(isolate, receiver, name); | |
| 1066 } | |
| 1067 Handle<Object> return_value = v8::Utils::OpenHandle(*result); | |
| 1068 return_value->VerifyApiCallResultType(); | |
| 1069 // Rebox handle before return. | 1064 // Rebox handle before return. |
| 1070 return handle(*return_value, isolate); | 1065 return handle(*result, isolate); |
| 1071 } | 1066 } |
| 1072 | 1067 |
| 1073 // Regular accessor. | 1068 // Regular accessor. |
| 1074 Handle<Object> getter(AccessorPair::cast(*structure)->getter(), isolate); | 1069 Handle<Object> getter(AccessorPair::cast(*structure)->getter(), isolate); |
| 1075 if (getter->IsFunctionTemplateInfo()) { | 1070 if (getter->IsFunctionTemplateInfo()) { |
| 1076 auto result = Builtins::InvokeApiFunction( | 1071 auto result = Builtins::InvokeApiFunction( |
| 1077 Handle<FunctionTemplateInfo>::cast(getter), receiver, 0, nullptr); | 1072 Handle<FunctionTemplateInfo>::cast(getter), receiver, 0, nullptr); |
| 1078 if (isolate->has_pending_exception()) { | 1073 if (isolate->has_pending_exception()) { |
| 1079 return MaybeHandle<Object>(); | 1074 return MaybeHandle<Object>(); |
| 1080 } | 1075 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1124 return Nothing<bool>(); | 1119 return Nothing<bool>(); |
| 1125 } | 1120 } |
| 1126 | 1121 |
| 1127 v8::AccessorNameSetterCallback call_fun = | 1122 v8::AccessorNameSetterCallback call_fun = |
| 1128 v8::ToCData<v8::AccessorNameSetterCallback>(info->setter()); | 1123 v8::ToCData<v8::AccessorNameSetterCallback>(info->setter()); |
| 1129 // TODO(verwaest): We should not get here anymore once all AccessorInfos are | 1124 // TODO(verwaest): We should not get here anymore once all AccessorInfos are |
| 1130 // marked as special_data_property. They cannot both be writable and not | 1125 // marked as special_data_property. They cannot both be writable and not |
| 1131 // have a setter. | 1126 // have a setter. |
| 1132 if (call_fun == nullptr) return Just(true); | 1127 if (call_fun == nullptr) return Just(true); |
| 1133 | 1128 |
| 1134 LOG(isolate, ApiNamedPropertyAccess("store", *holder, *name)); | |
| 1135 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder, | 1129 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder, |
| 1136 should_throw); | 1130 should_throw); |
| 1137 args.Call(call_fun, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value)); | 1131 args.Call(call_fun, name, value); |
| 1138 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); | 1132 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); |
| 1139 return Just(true); | 1133 return Just(true); |
| 1140 } | 1134 } |
| 1141 | 1135 |
| 1142 // Regular accessor. | 1136 // Regular accessor. |
| 1143 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); | 1137 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); |
| 1144 if (setter->IsFunctionTemplateInfo()) { | 1138 if (setter->IsFunctionTemplateInfo()) { |
| 1145 Handle<Object> argv[] = {value}; | 1139 Handle<Object> argv[] = {value}; |
| 1146 auto result = | 1140 auto result = |
| 1147 Builtins::InvokeApiFunction(Handle<FunctionTemplateInfo>::cast(setter), | 1141 Builtins::InvokeApiFunction(Handle<FunctionTemplateInfo>::cast(setter), |
| (...skipping 2917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4065 Isolate* isolate = it->isolate(); | 4059 Isolate* isolate = it->isolate(); |
| 4066 // Make sure that the top context does not change when doing callbacks or | 4060 // Make sure that the top context does not change when doing callbacks or |
| 4067 // interceptor calls. | 4061 // interceptor calls. |
| 4068 AssertNoContextChange ncc(isolate); | 4062 AssertNoContextChange ncc(isolate); |
| 4069 | 4063 |
| 4070 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); | 4064 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
| 4071 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); | 4065 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); |
| 4072 if (interceptor->setter()->IsUndefined()) return Just(false); | 4066 if (interceptor->setter()->IsUndefined()) return Just(false); |
| 4073 | 4067 |
| 4074 Handle<JSObject> holder = it->GetHolder<JSObject>(); | 4068 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 4075 v8::Local<v8::Value> result; | 4069 bool result; |
| 4076 PropertyCallbackArguments args(isolate, interceptor->data(), | 4070 PropertyCallbackArguments args(isolate, interceptor->data(), |
| 4077 *it->GetReceiver(), *holder, should_throw); | 4071 *it->GetReceiver(), *holder, should_throw); |
| 4078 | 4072 |
| 4079 if (it->IsElement()) { | 4073 if (it->IsElement()) { |
| 4080 uint32_t index = it->index(); | 4074 uint32_t index = it->index(); |
| 4081 v8::IndexedPropertySetterCallback setter = | 4075 v8::IndexedPropertySetterCallback setter = |
| 4082 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); | 4076 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); |
| 4083 LOG(isolate, | 4077 // TODO(neis): In the future, we may want to actually return the |
| 4084 ApiIndexedPropertyAccess("interceptor-indexed-set", *holder, index)); | 4078 // interceptor's result, which then should be a boolean. |
| 4085 result = args.Call(setter, index, v8::Utils::ToLocal(value)); | 4079 result = !args.Call(setter, index, value).is_null(); |
| 4086 } else { | 4080 } else { |
| 4087 Handle<Name> name = it->name(); | 4081 Handle<Name> name = it->name(); |
| 4088 DCHECK(!name->IsPrivate()); | 4082 DCHECK(!name->IsPrivate()); |
| 4089 | 4083 |
| 4090 if (name->IsSymbol() && !interceptor->can_intercept_symbols()) { | 4084 if (name->IsSymbol() && !interceptor->can_intercept_symbols()) { |
| 4091 return Just(false); | 4085 return Just(false); |
| 4092 } | 4086 } |
| 4093 | 4087 |
| 4094 v8::GenericNamedPropertySetterCallback setter = | 4088 v8::GenericNamedPropertySetterCallback setter = |
| 4095 v8::ToCData<v8::GenericNamedPropertySetterCallback>( | 4089 v8::ToCData<v8::GenericNamedPropertySetterCallback>( |
| 4096 interceptor->setter()); | 4090 interceptor->setter()); |
| 4097 LOG(it->isolate(), | 4091 result = !args.Call(setter, name, value).is_null(); |
| 4098 ApiNamedPropertyAccess("interceptor-named-set", *holder, *name)); | |
| 4099 result = | |
| 4100 args.Call(setter, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value)); | |
| 4101 } | 4092 } |
| 4102 | 4093 |
| 4103 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>()); | 4094 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>()); |
| 4104 if (result.IsEmpty()) return Just(false); | 4095 return Just(result); |
| 4105 #ifdef DEBUG | |
| 4106 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); | |
| 4107 result_internal->VerifyApiCallResultType(); | |
| 4108 #endif | |
| 4109 return Just(true); | |
| 4110 // TODO(neis): In the future, we may want to actually return the interceptor's | |
| 4111 // result, which then should be a boolean. | |
| 4112 } | 4096 } |
| 4113 | 4097 |
| 4114 | 4098 |
| 4115 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, | 4099 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, |
| 4116 Handle<Name> name, Handle<Object> value, | 4100 Handle<Name> name, Handle<Object> value, |
| 4117 LanguageMode language_mode, | 4101 LanguageMode language_mode, |
| 4118 StoreFromKeyed store_mode) { | 4102 StoreFromKeyed store_mode) { |
| 4119 LookupIterator it(object, name); | 4103 LookupIterator it(object, name); |
| 4120 MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode)); | 4104 MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode)); |
| 4121 return value; | 4105 return value; |
| (...skipping 1292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5414 Handle<JSObject> holder = it->GetHolder<JSObject>(); | 5398 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 5415 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); | 5399 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); |
| 5416 if (!it->IsElement() && it->name()->IsSymbol() && | 5400 if (!it->IsElement() && it->name()->IsSymbol() && |
| 5417 !interceptor->can_intercept_symbols()) { | 5401 !interceptor->can_intercept_symbols()) { |
| 5418 return Just(ABSENT); | 5402 return Just(ABSENT); |
| 5419 } | 5403 } |
| 5420 PropertyCallbackArguments args(isolate, interceptor->data(), | 5404 PropertyCallbackArguments args(isolate, interceptor->data(), |
| 5421 *it->GetReceiver(), *holder, | 5405 *it->GetReceiver(), *holder, |
| 5422 Object::DONT_THROW); | 5406 Object::DONT_THROW); |
| 5423 if (!interceptor->query()->IsUndefined()) { | 5407 if (!interceptor->query()->IsUndefined()) { |
| 5424 v8::Local<v8::Integer> result; | 5408 Handle<Object> result; |
| 5425 if (it->IsElement()) { | 5409 if (it->IsElement()) { |
| 5426 uint32_t index = it->index(); | 5410 uint32_t index = it->index(); |
| 5427 v8::IndexedPropertyQueryCallback query = | 5411 v8::IndexedPropertyQueryCallback query = |
| 5428 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query()); | 5412 v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query()); |
| 5429 LOG(isolate, | |
| 5430 ApiIndexedPropertyAccess("interceptor-indexed-has", *holder, index)); | |
| 5431 result = args.Call(query, index); | 5413 result = args.Call(query, index); |
| 5432 } else { | 5414 } else { |
| 5433 Handle<Name> name = it->name(); | 5415 Handle<Name> name = it->name(); |
| 5434 DCHECK(!name->IsPrivate()); | 5416 DCHECK(!name->IsPrivate()); |
| 5435 v8::GenericNamedPropertyQueryCallback query = | 5417 v8::GenericNamedPropertyQueryCallback query = |
| 5436 v8::ToCData<v8::GenericNamedPropertyQueryCallback>( | 5418 v8::ToCData<v8::GenericNamedPropertyQueryCallback>( |
| 5437 interceptor->query()); | 5419 interceptor->query()); |
| 5438 LOG(isolate, | 5420 result = args.Call(query, name); |
| 5439 ApiNamedPropertyAccess("interceptor-named-has", *holder, *name)); | |
| 5440 result = args.Call(query, v8::Utils::ToLocal(name)); | |
| 5441 } | 5421 } |
| 5442 if (!result.IsEmpty()) { | 5422 if (!result.is_null()) { |
| 5443 DCHECK(result->IsInt32()); | 5423 int32_t value; |
| 5444 return Just(static_cast<PropertyAttributes>( | 5424 CHECK(result->ToInt32(&value)); |
| 5445 result->Int32Value(reinterpret_cast<v8::Isolate*>(isolate) | 5425 return Just(static_cast<PropertyAttributes>(value)); |
| 5446 ->GetCurrentContext()).FromJust())); | |
| 5447 } | 5426 } |
| 5448 } else if (!interceptor->getter()->IsUndefined()) { | 5427 } else if (!interceptor->getter()->IsUndefined()) { |
| 5449 // TODO(verwaest): Use GetPropertyWithInterceptor? | 5428 // TODO(verwaest): Use GetPropertyWithInterceptor? |
| 5450 v8::Local<v8::Value> result; | 5429 Handle<Object> result; |
| 5451 if (it->IsElement()) { | 5430 if (it->IsElement()) { |
| 5452 uint32_t index = it->index(); | 5431 uint32_t index = it->index(); |
| 5453 v8::IndexedPropertyGetterCallback getter = | 5432 v8::IndexedPropertyGetterCallback getter = |
| 5454 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); | 5433 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); |
| 5455 LOG(isolate, ApiIndexedPropertyAccess("interceptor-indexed-get-has", | |
| 5456 *holder, index)); | |
| 5457 result = args.Call(getter, index); | 5434 result = args.Call(getter, index); |
| 5458 } else { | 5435 } else { |
| 5459 Handle<Name> name = it->name(); | 5436 Handle<Name> name = it->name(); |
| 5460 DCHECK(!name->IsPrivate()); | 5437 DCHECK(!name->IsPrivate()); |
| 5461 v8::GenericNamedPropertyGetterCallback getter = | 5438 v8::GenericNamedPropertyGetterCallback getter = |
| 5462 v8::ToCData<v8::GenericNamedPropertyGetterCallback>( | 5439 v8::ToCData<v8::GenericNamedPropertyGetterCallback>( |
| 5463 interceptor->getter()); | 5440 interceptor->getter()); |
| 5464 LOG(isolate, | 5441 result = args.Call(getter, name); |
| 5465 ApiNamedPropertyAccess("interceptor-named-get-has", *holder, *name)); | |
| 5466 result = args.Call(getter, v8::Utils::ToLocal(name)); | |
| 5467 } | 5442 } |
| 5468 if (!result.IsEmpty()) return Just(DONT_ENUM); | 5443 if (!result.is_null()) return Just(DONT_ENUM); |
| 5469 } | 5444 } |
| 5470 | 5445 |
| 5471 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>()); | 5446 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>()); |
| 5472 return Just(ABSENT); | 5447 return Just(ABSENT); |
| 5473 } | 5448 } |
| 5474 | 5449 |
| 5475 | 5450 |
| 5476 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes( | 5451 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes( |
| 5477 LookupIterator* it) { | 5452 LookupIterator* it) { |
| 5478 for (; it->IsFound(); it->Next()) { | 5453 for (; it->IsFound(); it->Next()) { |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6070 AssertNoContextChange ncc(isolate); | 6045 AssertNoContextChange ncc(isolate); |
| 6071 | 6046 |
| 6072 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); | 6047 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
| 6073 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); | 6048 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); |
| 6074 if (interceptor->deleter()->IsUndefined()) return Nothing<bool>(); | 6049 if (interceptor->deleter()->IsUndefined()) return Nothing<bool>(); |
| 6075 | 6050 |
| 6076 Handle<JSObject> holder = it->GetHolder<JSObject>(); | 6051 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 6077 | 6052 |
| 6078 PropertyCallbackArguments args(isolate, interceptor->data(), | 6053 PropertyCallbackArguments args(isolate, interceptor->data(), |
| 6079 *it->GetReceiver(), *holder, should_throw); | 6054 *it->GetReceiver(), *holder, should_throw); |
| 6080 v8::Local<v8::Boolean> result; | 6055 Handle<Object> result; |
| 6081 if (it->IsElement()) { | 6056 if (it->IsElement()) { |
| 6082 uint32_t index = it->index(); | 6057 uint32_t index = it->index(); |
| 6083 v8::IndexedPropertyDeleterCallback deleter = | 6058 v8::IndexedPropertyDeleterCallback deleter = |
| 6084 v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter()); | 6059 v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter()); |
| 6085 LOG(isolate, | |
| 6086 ApiIndexedPropertyAccess("interceptor-indexed-delete", *holder, index)); | |
| 6087 result = args.Call(deleter, index); | 6060 result = args.Call(deleter, index); |
| 6088 } else if (it->name()->IsSymbol() && !interceptor->can_intercept_symbols()) { | 6061 } else if (it->name()->IsSymbol() && !interceptor->can_intercept_symbols()) { |
| 6089 return Nothing<bool>(); | 6062 return Nothing<bool>(); |
| 6090 } else { | 6063 } else { |
| 6091 Handle<Name> name = it->name(); | 6064 Handle<Name> name = it->name(); |
| 6092 DCHECK(!name->IsPrivate()); | 6065 DCHECK(!name->IsPrivate()); |
| 6093 v8::GenericNamedPropertyDeleterCallback deleter = | 6066 v8::GenericNamedPropertyDeleterCallback deleter = |
| 6094 v8::ToCData<v8::GenericNamedPropertyDeleterCallback>( | 6067 v8::ToCData<v8::GenericNamedPropertyDeleterCallback>( |
| 6095 interceptor->deleter()); | 6068 interceptor->deleter()); |
| 6096 LOG(isolate, | 6069 result = args.Call(deleter, name); |
| 6097 ApiNamedPropertyAccess("interceptor-named-delete", *holder, *name)); | |
| 6098 result = args.Call(deleter, v8::Utils::ToLocal(name)); | |
| 6099 } | 6070 } |
| 6100 | 6071 |
| 6101 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); | 6072 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); |
| 6102 if (result.IsEmpty()) return Nothing<bool>(); | 6073 if (result.is_null()) return Nothing<bool>(); |
| 6103 | 6074 |
| 6104 DCHECK(result->IsBoolean()); | 6075 DCHECK(result->IsBoolean()); |
| 6105 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); | |
| 6106 result_internal->VerifyApiCallResultType(); | |
| 6107 // Rebox CustomArguments::kReturnValueOffset before returning. | 6076 // Rebox CustomArguments::kReturnValueOffset before returning. |
| 6108 return Just(result_internal->BooleanValue()); | 6077 return Just(result->IsTrue()); |
| 6109 } | 6078 } |
| 6110 | 6079 |
| 6111 | 6080 |
| 6112 void JSReceiver::DeleteNormalizedProperty(Handle<JSReceiver> object, | 6081 void JSReceiver::DeleteNormalizedProperty(Handle<JSReceiver> object, |
| 6113 Handle<Name> name, int entry) { | 6082 Handle<Name> name, int entry) { |
| 6114 DCHECK(!object->HasFastProperties()); | 6083 DCHECK(!object->HasFastProperties()); |
| 6115 Isolate* isolate = object->GetIsolate(); | 6084 Isolate* isolate = object->GetIsolate(); |
| 6116 | 6085 |
| 6117 if (object->IsJSGlobalObject()) { | 6086 if (object->IsJSGlobalObject()) { |
| 6118 // If we have a global object, invalidate the cell and swap in a new one. | 6087 // If we have a global object, invalidate the cell and swap in a new one. |
| (...skipping 2380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8499 } | 8468 } |
| 8500 Handle<InterceptorInfo> interceptor(type == kIndexed | 8469 Handle<InterceptorInfo> interceptor(type == kIndexed |
| 8501 ? object->GetIndexedInterceptor() | 8470 ? object->GetIndexedInterceptor() |
| 8502 : object->GetNamedInterceptor(), | 8471 : object->GetNamedInterceptor(), |
| 8503 isolate); | 8472 isolate); |
| 8504 if ((filter & ONLY_ALL_CAN_READ) && !interceptor->all_can_read()) { | 8473 if ((filter & ONLY_ALL_CAN_READ) && !interceptor->all_can_read()) { |
| 8505 return Just(true); | 8474 return Just(true); |
| 8506 } | 8475 } |
| 8507 PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, | 8476 PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, |
| 8508 *object, Object::DONT_THROW); | 8477 *object, Object::DONT_THROW); |
| 8509 v8::Local<v8::Object> result; | 8478 Handle<JSObject> result; |
| 8510 if (!interceptor->enumerator()->IsUndefined()) { | 8479 if (!interceptor->enumerator()->IsUndefined()) { |
| 8511 Callback enum_fun = v8::ToCData<Callback>(interceptor->enumerator()); | 8480 Callback enum_fun = v8::ToCData<Callback>(interceptor->enumerator()); |
| 8512 const char* log_tag = type == kIndexed ? "interceptor-indexed-enum" | 8481 const char* log_tag = type == kIndexed ? "interceptor-indexed-enum" |
| 8513 : "interceptor-named-enum"; | 8482 : "interceptor-named-enum"; |
| 8514 LOG(isolate, ApiObjectAccess(log_tag, *object)); | 8483 LOG(isolate, ApiObjectAccess(log_tag, *object)); |
| 8515 result = args.Call(enum_fun); | 8484 result = args.Call(enum_fun); |
| 8516 } | 8485 } |
| 8517 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); | 8486 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); |
| 8518 if (result.IsEmpty()) return Just(true); | 8487 if (result.is_null()) return Just(true); |
| 8519 DCHECK(v8::Utils::OpenHandle(*result)->IsJSArray() || | 8488 DCHECK(result->IsJSArray() || result->HasSloppyArgumentsElements()); |
| 8520 (v8::Utils::OpenHandle(*result)->IsJSObject() && | |
| 8521 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result)) | |
| 8522 ->HasSloppyArgumentsElements())); | |
| 8523 // The accumulator takes care of string/symbol filtering. | 8489 // The accumulator takes care of string/symbol filtering. |
| 8524 if (type == kIndexed) { | 8490 if (type == kIndexed) { |
| 8525 accumulator->AddElementKeysFromInterceptor( | 8491 accumulator->AddElementKeysFromInterceptor(result); |
| 8526 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result))); | |
| 8527 } else { | 8492 } else { |
| 8528 accumulator->AddKeys(Handle<JSObject>::cast(v8::Utils::OpenHandle(*result)), | 8493 accumulator->AddKeys(result, DO_NOT_CONVERT); |
| 8529 DO_NOT_CONVERT); | |
| 8530 } | 8494 } |
| 8531 return Just(true); | 8495 return Just(true); |
| 8532 } | 8496 } |
| 8533 | 8497 |
| 8534 | 8498 |
| 8535 // Returns |true| on success, |false| if prototype walking should be stopped, | 8499 // Returns |true| on success, |false| if prototype walking should be stopped, |
| 8536 // |nothing| if an exception was thrown. | 8500 // |nothing| if an exception was thrown. |
| 8537 static Maybe<bool> GetKeysFromJSObject(Isolate* isolate, | 8501 static Maybe<bool> GetKeysFromJSObject(Isolate* isolate, |
| 8538 Handle<JSReceiver> receiver, | 8502 Handle<JSReceiver> receiver, |
| 8539 Handle<JSObject> object, | 8503 Handle<JSObject> object, |
| (...skipping 7778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16318 // interceptor calls. | 16282 // interceptor calls. |
| 16319 AssertNoContextChange ncc(isolate); | 16283 AssertNoContextChange ncc(isolate); |
| 16320 | 16284 |
| 16321 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); | 16285 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
| 16322 Handle<InterceptorInfo> interceptor = it->GetInterceptor(); | 16286 Handle<InterceptorInfo> interceptor = it->GetInterceptor(); |
| 16323 if (interceptor->getter()->IsUndefined()) { | 16287 if (interceptor->getter()->IsUndefined()) { |
| 16324 return isolate->factory()->undefined_value(); | 16288 return isolate->factory()->undefined_value(); |
| 16325 } | 16289 } |
| 16326 | 16290 |
| 16327 Handle<JSObject> holder = it->GetHolder<JSObject>(); | 16291 Handle<JSObject> holder = it->GetHolder<JSObject>(); |
| 16328 v8::Local<v8::Value> result; | 16292 Handle<Object> result; |
| 16329 PropertyCallbackArguments args(isolate, interceptor->data(), | 16293 PropertyCallbackArguments args(isolate, interceptor->data(), |
| 16330 *it->GetReceiver(), *holder, | 16294 *it->GetReceiver(), *holder, |
| 16331 Object::DONT_THROW); | 16295 Object::DONT_THROW); |
| 16332 | 16296 |
| 16333 if (it->IsElement()) { | 16297 if (it->IsElement()) { |
| 16334 uint32_t index = it->index(); | 16298 uint32_t index = it->index(); |
| 16335 v8::IndexedPropertyGetterCallback getter = | 16299 v8::IndexedPropertyGetterCallback getter = |
| 16336 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); | 16300 v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter()); |
| 16337 LOG(isolate, | |
| 16338 ApiIndexedPropertyAccess("interceptor-indexed-get", *holder, index)); | |
| 16339 result = args.Call(getter, index); | 16301 result = args.Call(getter, index); |
| 16340 } else { | 16302 } else { |
| 16341 Handle<Name> name = it->name(); | 16303 Handle<Name> name = it->name(); |
| 16342 DCHECK(!name->IsPrivate()); | 16304 DCHECK(!name->IsPrivate()); |
| 16343 | 16305 |
| 16344 if (name->IsSymbol() && !interceptor->can_intercept_symbols()) { | 16306 if (name->IsSymbol() && !interceptor->can_intercept_symbols()) { |
| 16345 return isolate->factory()->undefined_value(); | 16307 return isolate->factory()->undefined_value(); |
| 16346 } | 16308 } |
| 16347 | 16309 |
| 16348 v8::GenericNamedPropertyGetterCallback getter = | 16310 v8::GenericNamedPropertyGetterCallback getter = |
| 16349 v8::ToCData<v8::GenericNamedPropertyGetterCallback>( | 16311 v8::ToCData<v8::GenericNamedPropertyGetterCallback>( |
| 16350 interceptor->getter()); | 16312 interceptor->getter()); |
| 16351 LOG(isolate, | 16313 result = args.Call(getter, name); |
| 16352 ApiNamedPropertyAccess("interceptor-named-get", *holder, *name)); | |
| 16353 result = args.Call(getter, v8::Utils::ToLocal(name)); | |
| 16354 } | 16314 } |
| 16355 | 16315 |
| 16356 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 16316 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 16357 if (result.IsEmpty()) return isolate->factory()->undefined_value(); | 16317 if (result.is_null()) return isolate->factory()->undefined_value(); |
| 16358 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); | |
| 16359 result_internal->VerifyApiCallResultType(); | |
| 16360 *done = true; | 16318 *done = true; |
| 16361 // Rebox handle before return | 16319 // Rebox handle before return |
| 16362 return handle(*result_internal, isolate); | 16320 return handle(*result, isolate); |
| 16363 } | 16321 } |
| 16364 | 16322 |
| 16365 | 16323 |
| 16366 Maybe<bool> JSObject::HasRealNamedProperty(Handle<JSObject> object, | 16324 Maybe<bool> JSObject::HasRealNamedProperty(Handle<JSObject> object, |
| 16367 Handle<Name> name) { | 16325 Handle<Name> name) { |
| 16368 LookupIterator it = LookupIterator::PropertyOrElement( | 16326 LookupIterator it = LookupIterator::PropertyOrElement( |
| 16369 name->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); | 16327 name->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 16370 return HasProperty(&it); | 16328 return HasProperty(&it); |
| 16371 } | 16329 } |
| 16372 | 16330 |
| (...skipping 3468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19841 if (cell->value() != *new_value) { | 19799 if (cell->value() != *new_value) { |
| 19842 cell->set_value(*new_value); | 19800 cell->set_value(*new_value); |
| 19843 Isolate* isolate = cell->GetIsolate(); | 19801 Isolate* isolate = cell->GetIsolate(); |
| 19844 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19802 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 19845 isolate, DependentCode::kPropertyCellChangedGroup); | 19803 isolate, DependentCode::kPropertyCellChangedGroup); |
| 19846 } | 19804 } |
| 19847 } | 19805 } |
| 19848 | 19806 |
| 19849 } // namespace internal | 19807 } // namespace internal |
| 19850 } // namespace v8 | 19808 } // namespace v8 |
| OLD | NEW |