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/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 8157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8168 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result))); | 8168 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result))); |
8169 } else { | 8169 } else { |
8170 accumulator->AddKeys( | 8170 accumulator->AddKeys( |
8171 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result))); | 8171 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result))); |
8172 } | 8172 } |
8173 return true; | 8173 return true; |
8174 } | 8174 } |
8175 | 8175 |
8176 | 8176 |
8177 static bool GetKeysFromJSObject(Isolate* isolate, Handle<JSReceiver> receiver, | 8177 static bool GetKeysFromJSObject(Isolate* isolate, Handle<JSReceiver> receiver, |
8178 Handle<JSObject> object, PropertyFilter filter, | 8178 Handle<JSObject> object, PropertyFilter* filter, |
Jakob Kummerow
2015/12/04 13:39:29
If you have any better ideas than passing |filter|
Camillo Bruni
2015/12/04 14:37:16
we might want to push all of this onto the KeyAccu
| |
8179 JSReceiver::KeyCollectionType type, | 8179 JSReceiver::KeyCollectionType type, |
8180 KeyAccumulator* accumulator) { | 8180 KeyAccumulator* accumulator) { |
8181 accumulator->NextPrototype(); | 8181 accumulator->NextPrototype(); |
8182 bool keep_going = true; | |
8183 // Check access rights if required. | 8182 // Check access rights if required. |
8184 if (object->IsAccessCheckNeeded() && | 8183 if (object->IsAccessCheckNeeded() && |
8185 !isolate->MayAccess(handle(isolate->context()), object)) { | 8184 !isolate->MayAccess(handle(isolate->context()), object)) { |
8186 // The cross-origin spec says that [[Enumerate]] shall return an empty | 8185 // The cross-origin spec says that [[Enumerate]] shall return an empty |
8187 // iterator when it doesn't have access... | 8186 // iterator when it doesn't have access... |
8188 if (type == JSReceiver::INCLUDE_PROTOS) { | 8187 if (type == JSReceiver::INCLUDE_PROTOS) { |
8189 return false; | 8188 return false; |
8190 } | 8189 } |
8191 // ...whereas [[OwnPropertyKeys]] shall return whitelisted properties. | 8190 // ...whereas [[OwnPropertyKeys]] shall return whitelisted properties. |
8192 DCHECK(type == JSReceiver::OWN_ONLY); | 8191 DCHECK(type == JSReceiver::OWN_ONLY); |
8193 filter = static_cast<PropertyFilter>(filter | ONLY_ALL_CAN_READ); | 8192 *filter = static_cast<PropertyFilter>(*filter | ONLY_ALL_CAN_READ); |
8194 keep_going = false; | |
8195 | |
8196 // TODO(jkummerow): LayoutTests need adaptation before we can be spec | |
Jakob Kummerow
2015/12/04 13:39:29
Waiting for https://codereview.chromium.org/150345
| |
8197 // compliant. | |
8198 // Let [[OwnPropertyKeys]] also return an empty list for now. | |
8199 return false; | |
8200 } | 8193 } |
8201 | 8194 |
8202 JSObject::CollectOwnElementKeys(object, accumulator, filter); | 8195 JSObject::CollectOwnElementKeys(object, accumulator, *filter); |
8203 | 8196 |
8204 // Add the element keys from the interceptor. | 8197 // Add the element keys from the interceptor. |
8205 if (!GetKeysFromInterceptor<v8::IndexedPropertyEnumeratorCallback, kIndexed>( | 8198 if (!GetKeysFromInterceptor<v8::IndexedPropertyEnumeratorCallback, kIndexed>( |
8206 isolate, receiver, object, filter, accumulator)) { | 8199 isolate, receiver, object, *filter, accumulator)) { |
8207 DCHECK(isolate->has_pending_exception()); | 8200 DCHECK(isolate->has_pending_exception()); |
8208 return false; | 8201 return false; |
8209 } | 8202 } |
8210 | 8203 |
8211 if (filter == ENUMERABLE_STRINGS) { | 8204 if (*filter == ENUMERABLE_STRINGS) { |
8212 // We can cache the computed property keys if access checks are | 8205 // We can cache the computed property keys if access checks are |
8213 // not needed and no interceptors are involved. | 8206 // not needed and no interceptors are involved. |
8214 // | 8207 // |
8215 // We do not use the cache if the object has elements and | 8208 // We do not use the cache if the object has elements and |
8216 // therefore it does not make sense to cache the property names | 8209 // therefore it does not make sense to cache the property names |
8217 // for arguments objects. Arguments objects will always have | 8210 // for arguments objects. Arguments objects will always have |
8218 // elements. | 8211 // elements. |
8219 // Wrapped strings have elements, but don't have an elements | 8212 // Wrapped strings have elements, but don't have an elements |
8220 // array or dictionary. So the fast inline test for whether to | 8213 // array or dictionary. So the fast inline test for whether to |
8221 // use the cache says yes, so we should not create a cache. | 8214 // use the cache says yes, so we should not create a cache. |
8222 Handle<JSFunction> arguments_function( | 8215 Handle<JSFunction> arguments_function( |
8223 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); | 8216 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor())); |
8224 bool cache_enum_length = | 8217 bool cache_enum_length = |
8225 ((object->map()->GetConstructor() != *arguments_function) && | 8218 ((object->map()->GetConstructor() != *arguments_function) && |
8226 !object->IsJSValue() && !object->IsAccessCheckNeeded() && | 8219 !object->IsJSValue() && !object->IsAccessCheckNeeded() && |
8227 !object->HasNamedInterceptor() && !object->HasIndexedInterceptor()); | 8220 !object->HasNamedInterceptor() && !object->HasIndexedInterceptor()); |
8228 // Compute the property keys and cache them if possible. | 8221 // Compute the property keys and cache them if possible. |
8229 Handle<FixedArray> enum_keys = | 8222 Handle<FixedArray> enum_keys = |
8230 JSObject::GetEnumPropertyKeys(object, cache_enum_length); | 8223 JSObject::GetEnumPropertyKeys(object, cache_enum_length); |
8231 accumulator->AddKeys(enum_keys); | 8224 accumulator->AddKeys(enum_keys); |
8232 } else { | 8225 } else { |
8233 object->CollectOwnPropertyNames(accumulator, filter); | 8226 object->CollectOwnPropertyNames(accumulator, *filter); |
8234 } | 8227 } |
8235 | 8228 |
8236 // Add the property keys from the interceptor. | 8229 // Add the property keys from the interceptor. |
8237 if (!GetKeysFromInterceptor<v8::GenericNamedPropertyEnumeratorCallback, | 8230 if (!GetKeysFromInterceptor<v8::GenericNamedPropertyEnumeratorCallback, |
8238 kNamed>(isolate, receiver, object, filter, | 8231 kNamed>(isolate, receiver, object, *filter, |
8239 accumulator)) { | 8232 accumulator)) { |
8240 DCHECK(isolate->has_pending_exception()); | 8233 DCHECK(isolate->has_pending_exception()); |
8241 return false; | 8234 return false; |
8242 } | 8235 } |
8243 return keep_going; | 8236 return true; |
8244 } | 8237 } |
8245 | 8238 |
8246 | 8239 |
8247 // Helper function for JSReceiver::GetKeys() below. Can be called recursively. | 8240 // Helper function for JSReceiver::GetKeys() below. Can be called recursively. |
8248 // Returns false iff an exception was thrown. | 8241 // Returns false iff an exception was thrown. |
8249 static bool GetKeys_Internal(Isolate* isolate, Handle<JSReceiver> receiver, | 8242 static bool GetKeys_Internal(Isolate* isolate, Handle<JSReceiver> receiver, |
8250 Handle<JSReceiver> object, | 8243 Handle<JSReceiver> object, |
8251 JSReceiver::KeyCollectionType type, | 8244 JSReceiver::KeyCollectionType type, |
8252 PropertyFilter filter, | 8245 PropertyFilter filter, |
8253 KeyAccumulator* accumulator) { | 8246 KeyAccumulator* accumulator) { |
(...skipping 12 matching lines...) Expand all Loading... | |
8266 Handle<JSProxy>::cast(current), | 8259 Handle<JSProxy>::cast(current), |
8267 filter, accumulator); | 8260 filter, accumulator); |
8268 } else { | 8261 } else { |
8269 DCHECK(type == JSReceiver::INCLUDE_PROTOS); | 8262 DCHECK(type == JSReceiver::INCLUDE_PROTOS); |
8270 result = JSProxy::Enumerate( | 8263 result = JSProxy::Enumerate( |
8271 isolate, receiver, Handle<JSProxy>::cast(current), accumulator); | 8264 isolate, receiver, Handle<JSProxy>::cast(current), accumulator); |
8272 } | 8265 } |
8273 } else { | 8266 } else { |
8274 DCHECK(current->IsJSObject()); | 8267 DCHECK(current->IsJSObject()); |
8275 result = GetKeysFromJSObject(isolate, receiver, | 8268 result = GetKeysFromJSObject(isolate, receiver, |
8276 Handle<JSObject>::cast(current), filter, | 8269 Handle<JSObject>::cast(current), &filter, |
8277 type, accumulator); | 8270 type, accumulator); |
8278 } | 8271 } |
8279 if (!result) { | 8272 if (!result) { |
8280 if (isolate->has_pending_exception()) { | 8273 if (isolate->has_pending_exception()) { |
8281 return false; | 8274 return false; |
8282 } | 8275 } |
8283 // If there was no exception, then "false" means "stop iterating". | 8276 // If there was no exception, then "false" means "stop iterating". |
8284 break; | 8277 break; |
8285 } | 8278 } |
8286 } | 8279 } |
(...skipping 7360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15647 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 15640 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
15648 if (result.IsEmpty()) return isolate->factory()->undefined_value(); | 15641 if (result.IsEmpty()) return isolate->factory()->undefined_value(); |
15649 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); | 15642 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); |
15650 result_internal->VerifyApiCallResultType(); | 15643 result_internal->VerifyApiCallResultType(); |
15651 *done = true; | 15644 *done = true; |
15652 // Rebox handle before return | 15645 // Rebox handle before return |
15653 return handle(*result_internal, isolate); | 15646 return handle(*result_internal, isolate); |
15654 } | 15647 } |
15655 | 15648 |
15656 | 15649 |
15657 // Compute the property keys from the interceptor. | |
15658 // TODO(jkummerow): Deprecated. | |
15659 MaybeHandle<JSObject> JSObject::GetKeysForNamedInterceptor( | |
15660 Handle<JSObject> object, Handle<JSReceiver> receiver) { | |
15661 Isolate* isolate = receiver->GetIsolate(); | |
15662 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); | |
15663 PropertyCallbackArguments | |
15664 args(isolate, interceptor->data(), *receiver, *object); | |
15665 v8::Local<v8::Object> result; | |
15666 if (!interceptor->enumerator()->IsUndefined()) { | |
15667 v8::GenericNamedPropertyEnumeratorCallback enum_fun = | |
15668 v8::ToCData<v8::GenericNamedPropertyEnumeratorCallback>( | |
15669 interceptor->enumerator()); | |
15670 LOG(isolate, ApiObjectAccess("interceptor-named-enum", *object)); | |
15671 result = args.Call(enum_fun); | |
15672 } | |
15673 if (result.IsEmpty()) return MaybeHandle<JSObject>(); | |
15674 DCHECK(v8::Utils::OpenHandle(*result)->IsJSArray() || | |
15675 (v8::Utils::OpenHandle(*result)->IsJSObject() && | |
15676 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result)) | |
15677 ->HasSloppyArgumentsElements())); | |
15678 // Rebox before returning. | |
15679 return handle(JSObject::cast(*v8::Utils::OpenHandle(*result)), isolate); | |
15680 } | |
15681 | |
15682 | |
15683 // Compute the element keys from the interceptor. | |
15684 // TODO(jkummerow): Deprecated. | |
15685 MaybeHandle<JSObject> JSObject::GetKeysForIndexedInterceptor( | |
15686 Handle<JSObject> object, Handle<JSReceiver> receiver) { | |
15687 Isolate* isolate = receiver->GetIsolate(); | |
15688 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); | |
15689 PropertyCallbackArguments | |
15690 args(isolate, interceptor->data(), *receiver, *object); | |
15691 v8::Local<v8::Object> result; | |
15692 if (!interceptor->enumerator()->IsUndefined()) { | |
15693 v8::IndexedPropertyEnumeratorCallback enum_fun = | |
15694 v8::ToCData<v8::IndexedPropertyEnumeratorCallback>( | |
15695 interceptor->enumerator()); | |
15696 LOG(isolate, ApiObjectAccess("interceptor-indexed-enum", *object)); | |
15697 result = args.Call(enum_fun); | |
15698 } | |
15699 if (result.IsEmpty()) return MaybeHandle<JSObject>(); | |
15700 DCHECK(v8::Utils::OpenHandle(*result)->IsJSArray() || | |
15701 (v8::Utils::OpenHandle(*result)->IsJSObject() && | |
15702 Handle<JSObject>::cast(v8::Utils::OpenHandle(*result)) | |
15703 ->HasSloppyArgumentsElements())); | |
15704 // Rebox before returning. | |
15705 return handle(JSObject::cast(*v8::Utils::OpenHandle(*result)), isolate); | |
15706 } | |
15707 | |
15708 | |
15709 Maybe<bool> JSObject::HasRealNamedProperty(Handle<JSObject> object, | 15650 Maybe<bool> JSObject::HasRealNamedProperty(Handle<JSObject> object, |
15710 Handle<Name> name) { | 15651 Handle<Name> name) { |
15711 LookupIterator it = LookupIterator::PropertyOrElement( | 15652 LookupIterator it = LookupIterator::PropertyOrElement( |
15712 name->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); | 15653 name->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); |
15713 return HasProperty(&it); | 15654 return HasProperty(&it); |
15714 } | 15655 } |
15715 | 15656 |
15716 | 15657 |
15717 Maybe<bool> JSObject::HasRealElementProperty(Handle<JSObject> object, | 15658 Maybe<bool> JSObject::HasRealElementProperty(Handle<JSObject> object, |
15718 uint32_t index) { | 15659 uint32_t index) { |
(...skipping 2183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
17902 Dictionary<Derived, Shape, Key>* raw_dict = *dictionary; | 17843 Dictionary<Derived, Shape, Key>* raw_dict = *dictionary; |
17903 for (int i = 0; i < capacity; i++) { | 17844 for (int i = 0; i < capacity; i++) { |
17904 Object* k = raw_dict->KeyAt(i); | 17845 Object* k = raw_dict->KeyAt(i); |
17905 if (!raw_dict->IsKey(k) || k->FilterKey(filter)) continue; | 17846 if (!raw_dict->IsKey(k) || k->FilterKey(filter)) continue; |
17906 if (raw_dict->IsDeleted(i)) continue; | 17847 if (raw_dict->IsDeleted(i)) continue; |
17907 PropertyDetails details = raw_dict->DetailsAt(i); | 17848 PropertyDetails details = raw_dict->DetailsAt(i); |
17908 if ((details.attributes() & filter) != 0) continue; | 17849 if ((details.attributes() & filter) != 0) continue; |
17909 if (filter & ONLY_ALL_CAN_READ) { | 17850 if (filter & ONLY_ALL_CAN_READ) { |
17910 if (details.kind() != kAccessor) continue; | 17851 if (details.kind() != kAccessor) continue; |
17911 Object* accessors = raw_dict->ValueAt(i); | 17852 Object* accessors = raw_dict->ValueAt(i); |
17853 if (accessors->IsPropertyCell()) { | |
Jakob Kummerow
2015/12/04 13:39:29
cf. line 17883.
| |
17854 accessors = PropertyCell::cast(accessors)->value(); | |
17855 } | |
17912 if (!accessors->IsAccessorInfo()) continue; | 17856 if (!accessors->IsAccessorInfo()) continue; |
17913 if (!AccessorInfo::cast(accessors)->all_can_read()) continue; | 17857 if (!AccessorInfo::cast(accessors)->all_can_read()) continue; |
17914 } | 17858 } |
17915 array->set(array_size++, Smi::FromInt(i)); | 17859 array->set(array_size++, Smi::FromInt(i)); |
17916 } | 17860 } |
17917 | 17861 |
17918 EnumIndexComparator<Derived> cmp(static_cast<Derived*>(raw_dict)); | 17862 EnumIndexComparator<Derived> cmp(static_cast<Derived*>(raw_dict)); |
17919 Smi** start = reinterpret_cast<Smi**>(array->GetFirstElementAddress()); | 17863 Smi** start = reinterpret_cast<Smi**>(array->GetFirstElementAddress()); |
17920 std::sort(start, start + array_size, cmp); | 17864 std::sort(start, start + array_size, cmp); |
17921 } | 17865 } |
(...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
19129 if (cell->value() != *new_value) { | 19073 if (cell->value() != *new_value) { |
19130 cell->set_value(*new_value); | 19074 cell->set_value(*new_value); |
19131 Isolate* isolate = cell->GetIsolate(); | 19075 Isolate* isolate = cell->GetIsolate(); |
19132 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19076 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
19133 isolate, DependentCode::kPropertyCellChangedGroup); | 19077 isolate, DependentCode::kPropertyCellChangedGroup); |
19134 } | 19078 } |
19135 } | 19079 } |
19136 | 19080 |
19137 } // namespace internal | 19081 } // namespace internal |
19138 } // namespace v8 | 19082 } // namespace v8 |
OLD | NEW |