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 10 matching lines...) Expand all Loading... |
21 #include "src/compiler.h" | 21 #include "src/compiler.h" |
22 #include "src/date.h" | 22 #include "src/date.h" |
23 #include "src/debug/debug.h" | 23 #include "src/debug/debug.h" |
24 #include "src/deoptimizer.h" | 24 #include "src/deoptimizer.h" |
25 #include "src/elements.h" | 25 #include "src/elements.h" |
26 #include "src/execution.h" | 26 #include "src/execution.h" |
27 #include "src/field-index.h" | 27 #include "src/field-index.h" |
28 #include "src/field-index-inl.h" | 28 #include "src/field-index-inl.h" |
29 #include "src/full-codegen/full-codegen.h" | 29 #include "src/full-codegen/full-codegen.h" |
30 #include "src/ic/ic.h" | 30 #include "src/ic/ic.h" |
| 31 #include "src/identity-map.h" |
31 #include "src/interpreter/bytecodes.h" | 32 #include "src/interpreter/bytecodes.h" |
32 #include "src/isolate-inl.h" | 33 #include "src/isolate-inl.h" |
33 #include "src/key-accumulator.h" | 34 #include "src/key-accumulator.h" |
34 #include "src/list.h" | 35 #include "src/list.h" |
35 #include "src/log.h" | 36 #include "src/log.h" |
36 #include "src/lookup.h" | 37 #include "src/lookup.h" |
37 #include "src/macro-assembler.h" | 38 #include "src/macro-assembler.h" |
38 #include "src/messages.h" | 39 #include "src/messages.h" |
39 #include "src/objects-inl.h" | 40 #include "src/objects-inl.h" |
40 #include "src/objects-body-descriptors-inl.h" | 41 #include "src/objects-body-descriptors-inl.h" |
41 #include "src/profiler/cpu-profiler.h" | 42 #include "src/profiler/cpu-profiler.h" |
42 #include "src/property-descriptor.h" | 43 #include "src/property-descriptor.h" |
43 #include "src/prototype.h" | 44 #include "src/prototype.h" |
44 #include "src/safepoint-table.h" | 45 #include "src/safepoint-table.h" |
45 #include "src/string-builder.h" | 46 #include "src/string-builder.h" |
46 #include "src/string-search.h" | 47 #include "src/string-search.h" |
47 #include "src/string-stream.h" | 48 #include "src/string-stream.h" |
48 #include "src/utils.h" | 49 #include "src/utils.h" |
| 50 #include "src/zone.h" |
49 | 51 |
50 #ifdef ENABLE_DISASSEMBLER | 52 #ifdef ENABLE_DISASSEMBLER |
51 #include "src/disasm.h" | 53 #include "src/disasm.h" |
52 #include "src/disassembler.h" | 54 #include "src/disassembler.h" |
53 #endif | 55 #endif |
54 | 56 |
55 namespace v8 { | 57 namespace v8 { |
56 namespace internal { | 58 namespace internal { |
57 | 59 |
58 Handle<HeapType> Object::OptimalType(Isolate* isolate, | 60 Handle<HeapType> Object::OptimalType(Isolate* isolate, |
(...skipping 7925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7984 dictionary->CopyEnumKeysTo(*storage); | 7986 dictionary->CopyEnumKeysTo(*storage); |
7985 return storage; | 7987 return storage; |
7986 } | 7988 } |
7987 } | 7989 } |
7988 | 7990 |
7989 | 7991 |
7990 static bool GetKeysFromJSObject(Isolate* isolate, Handle<JSReceiver> receiver, | 7992 static bool GetKeysFromJSObject(Isolate* isolate, Handle<JSReceiver> receiver, |
7991 Handle<JSObject> object, KeyFilter filter, | 7993 Handle<JSObject> object, KeyFilter filter, |
7992 Enumerability enum_policy, | 7994 Enumerability enum_policy, |
7993 KeyAccumulator* accumulator) { | 7995 KeyAccumulator* accumulator) { |
| 7996 accumulator->NextPrototype(); |
7994 // Check access rights if required. | 7997 // Check access rights if required. |
7995 if (object->IsAccessCheckNeeded() && | 7998 if (object->IsAccessCheckNeeded() && |
7996 !isolate->MayAccess(handle(isolate->context()), object)) { | 7999 !isolate->MayAccess(handle(isolate->context()), object)) { |
7997 // TODO(jkummerow): Get whitelisted (all-can-read) keys. | 8000 // TODO(jkummerow): Get whitelisted (all-can-read) keys. |
7998 // It's probably best to implement a "GetKeysWithFailedAccessCheck" | 8001 // It's probably best to implement a "GetKeysWithFailedAccessCheck" |
7999 // helper, which will need to look at both interceptors and accessors. | 8002 // helper, which will need to look at both interceptors and accessors. |
8000 return false; | 8003 return false; |
8001 } | 8004 } |
8002 | 8005 |
8003 PropertyAttributes attr_filter = static_cast<PropertyAttributes>( | 8006 PropertyAttributes attr_filter = static_cast<PropertyAttributes>( |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8063 Handle<JSReceiver> object, | 8066 Handle<JSReceiver> object, |
8064 JSReceiver::KeyCollectionType type, | 8067 JSReceiver::KeyCollectionType type, |
8065 KeyFilter filter, Enumerability enum_policy, | 8068 KeyFilter filter, Enumerability enum_policy, |
8066 KeyAccumulator* accumulator) { | 8069 KeyAccumulator* accumulator) { |
8067 PrototypeIterator::WhereToEnd end = type == JSReceiver::OWN_ONLY | 8070 PrototypeIterator::WhereToEnd end = type == JSReceiver::OWN_ONLY |
8068 ? PrototypeIterator::END_AT_NON_HIDDEN | 8071 ? PrototypeIterator::END_AT_NON_HIDDEN |
8069 : PrototypeIterator::END_AT_NULL; | 8072 : PrototypeIterator::END_AT_NULL; |
8070 for (PrototypeIterator iter(isolate, object, | 8073 for (PrototypeIterator iter(isolate, object, |
8071 PrototypeIterator::START_AT_RECEIVER); | 8074 PrototypeIterator::START_AT_RECEIVER); |
8072 !iter.IsAtEnd(end); iter.Advance()) { | 8075 !iter.IsAtEnd(end); iter.Advance()) { |
8073 accumulator->NextPrototype(); | |
8074 Handle<JSReceiver> current = | 8076 Handle<JSReceiver> current = |
8075 PrototypeIterator::GetCurrent<JSReceiver>(iter); | 8077 PrototypeIterator::GetCurrent<JSReceiver>(iter); |
8076 bool result = false; | 8078 bool result = false; |
8077 if (current->IsJSProxy()) { | 8079 if (current->IsJSProxy()) { |
8078 Handle<Object> args[] = {current}; | 8080 if (type == JSReceiver::OWN_ONLY) { |
8079 Handle<Object> names; | 8081 result = JSProxy::OwnPropertyKeys(isolate, receiver, |
8080 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 8082 Handle<JSProxy>::cast(current), |
8081 isolate, names, Execution::Call(isolate, isolate->proxy_enumerate(), | 8083 filter, enum_policy, accumulator); |
8082 current, arraysize(args), args), | 8084 } else { |
8083 false); | 8085 DCHECK(type == JSReceiver::INCLUDE_PROTOS); |
8084 accumulator->AddKeysFromProxy(Handle<JSObject>::cast(names)); | 8086 result = JSProxy::Enumerate( |
| 8087 isolate, receiver, Handle<JSProxy>::cast(current), accumulator); |
| 8088 } |
8085 } else { | 8089 } else { |
8086 DCHECK(current->IsJSObject()); | 8090 DCHECK(current->IsJSObject()); |
8087 result = GetKeysFromJSObject(isolate, receiver, | 8091 result = GetKeysFromJSObject(isolate, receiver, |
8088 Handle<JSObject>::cast(current), filter, | 8092 Handle<JSObject>::cast(current), filter, |
8089 enum_policy, accumulator); | 8093 enum_policy, accumulator); |
8090 } | 8094 } |
8091 if (!result) { | 8095 if (!result) { |
8092 if (isolate->has_pending_exception()) { | 8096 if (isolate->has_pending_exception()) { |
8093 return false; | 8097 return false; |
8094 } | 8098 } |
8095 // If there was no exception, then "false" means "stop iterating". | 8099 // If there was no exception, then "false" means "stop iterating". |
8096 break; | 8100 break; |
8097 } | 8101 } |
8098 } | 8102 } |
8099 return true; | 8103 return true; |
8100 } | 8104 } |
8101 | 8105 |
8102 | 8106 |
| 8107 // ES6 9.5.11 |
| 8108 // Returns false in case of exception. |
| 8109 // static |
| 8110 bool JSProxy::Enumerate(Isolate* isolate, Handle<JSReceiver> receiver, |
| 8111 Handle<JSProxy> proxy, KeyAccumulator* accumulator) { |
| 8112 // 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. |
| 8113 Handle<Object> handler(proxy->handler(), isolate); |
| 8114 // 2. If handler is null, throw a TypeError exception. |
| 8115 if (IsRevoked(proxy)) { |
| 8116 isolate->Throw(*isolate->factory()->NewTypeError( |
| 8117 MessageTemplate::kProxyRevoked, |
| 8118 isolate->factory()->enumerate_string())); |
| 8119 return false; |
| 8120 } |
| 8121 // 3. Assert: Type(handler) is Object. |
| 8122 DCHECK(handler->IsJSReceiver()); |
| 8123 // 4. Let target be the value of the [[ProxyTarget]] internal slot of O. |
| 8124 Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate); |
| 8125 // 5. Let trap be ? GetMethod(handler, "enumerate"). |
| 8126 Handle<Object> trap; |
| 8127 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 8128 isolate, trap, Object::GetMethod(Handle<JSReceiver>::cast(handler), |
| 8129 isolate->factory()->enumerate_string()), |
| 8130 false); |
| 8131 // 6. If trap is undefined, then |
| 8132 if (trap->IsUndefined()) { |
| 8133 // 6a. Return target.[[Enumerate]](). |
| 8134 return GetKeys_Internal(isolate, receiver, target, INCLUDE_PROTOS, |
| 8135 SKIP_SYMBOLS, RESPECT_ENUMERABILITY, accumulator); |
| 8136 } |
| 8137 // The "proxy_enumerate" helper calls the trap (steps 7 - 9), which returns |
| 8138 // a generator; it then iterates over that generator until it's exhausted |
| 8139 // and returns an array containing the generated values. |
| 8140 Handle<Object> trap_result_array; |
| 8141 Handle<Object> args[] = {trap, handler, target}; |
| 8142 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 8143 isolate, trap_result_array, |
| 8144 Execution::Call(isolate, isolate->proxy_enumerate(), |
| 8145 isolate->factory()->undefined_value(), arraysize(args), |
| 8146 args), |
| 8147 false); |
| 8148 accumulator->NextPrototype(); |
| 8149 accumulator->AddKeysFromProxy(Handle<JSObject>::cast(trap_result_array)); |
| 8150 return true; |
| 8151 } |
| 8152 |
| 8153 |
| 8154 // ES6 7.3.17 for elementTypes = (String, Symbol) |
| 8155 static MaybeHandle<FixedArray> CreateListFromArrayLike_StringSymbol( |
| 8156 Isolate* isolate, Handle<Object> object) { |
| 8157 // 1. ReturnIfAbrupt(object). |
| 8158 // 2. (default elementTypes -- not applicable.) |
| 8159 // 3. If Type(obj) is not Object, throw a TypeError exception. |
| 8160 if (!object->IsJSReceiver()) { |
| 8161 isolate->Throw(*isolate->factory()->NewTypeError( |
| 8162 MessageTemplate::kCalledOnNonObject, |
| 8163 isolate->factory()->NewStringFromAsciiChecked( |
| 8164 "CreateListFromArrayLike"))); |
| 8165 return MaybeHandle<FixedArray>(); |
| 8166 } |
| 8167 // 4. Let len be ? ToLength(? Get(obj, "length")). |
| 8168 Handle<Object> raw_length_obj; |
| 8169 ASSIGN_RETURN_ON_EXCEPTION( |
| 8170 isolate, raw_length_obj, |
| 8171 JSReceiver::GetProperty(object, isolate->factory()->length_string()), |
| 8172 FixedArray); |
| 8173 Handle<Object> raw_length_number; |
| 8174 ASSIGN_RETURN_ON_EXCEPTION(isolate, raw_length_number, |
| 8175 Object::ToLength(isolate, raw_length_obj), |
| 8176 FixedArray); |
| 8177 uint32_t len; |
| 8178 if (!raw_length_number->ToUint32(&len) || |
| 8179 len > static_cast<uint32_t>(FixedArray::kMaxLength)) { |
| 8180 isolate->Throw(*isolate->factory()->NewRangeError( |
| 8181 MessageTemplate::kInvalidArrayLength)); |
| 8182 return MaybeHandle<FixedArray>(); |
| 8183 } |
| 8184 // 5. Let list be an empty List. |
| 8185 Handle<FixedArray> list = isolate->factory()->NewFixedArray(len); |
| 8186 // 6. Let index be 0. |
| 8187 // 7. Repeat while index < len: |
| 8188 for (uint32_t index = 0; index < len; ++index) { |
| 8189 // 7a. Let indexName be ToString(index). |
| 8190 // 7b. Let next be ? Get(obj, indexName). |
| 8191 Handle<Object> next; |
| 8192 ASSIGN_RETURN_ON_EXCEPTION( |
| 8193 isolate, next, Object::GetElement(isolate, object, index), FixedArray); |
| 8194 // 7c. If Type(next) is not an element of elementTypes, throw a |
| 8195 // TypeError exception. |
| 8196 if (!next->IsName()) { |
| 8197 isolate->Throw(*isolate->factory()->NewTypeError( |
| 8198 MessageTemplate::kNotPropertyName, next)); |
| 8199 return MaybeHandle<FixedArray>(); |
| 8200 } |
| 8201 // 7d. Append next as the last element of list. |
| 8202 // Internalize on the fly so we can use pointer identity later. |
| 8203 next = isolate->factory()->InternalizeName(Handle<Name>::cast(next)); |
| 8204 list->set(index, *next); |
| 8205 // 7e. Set index to index + 1. (See loop header.) |
| 8206 } |
| 8207 // 8. Return list. |
| 8208 return list; |
| 8209 } |
| 8210 |
| 8211 |
| 8212 // ES6 9.5.12 |
| 8213 // Returns "false" in case of exception. |
| 8214 // TODO(jkummerow): |filter| and |enum_policy| are currently ignored. |
| 8215 // static |
| 8216 bool JSProxy::OwnPropertyKeys(Isolate* isolate, Handle<JSReceiver> receiver, |
| 8217 Handle<JSProxy> proxy, KeyFilter filter, |
| 8218 Enumerability enum_policy, |
| 8219 KeyAccumulator* accumulator) { |
| 8220 // 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. |
| 8221 Handle<Object> handler(proxy->handler(), isolate); |
| 8222 // 2. If handler is null, throw a TypeError exception. |
| 8223 if (IsRevoked(proxy)) { |
| 8224 isolate->Throw(*isolate->factory()->NewTypeError( |
| 8225 MessageTemplate::kProxyRevoked, isolate->factory()->ownKeys_string())); |
| 8226 return false; |
| 8227 } |
| 8228 // 3. Assert: Type(handler) is Object. |
| 8229 DCHECK(handler->IsJSReceiver()); |
| 8230 // 4. Let target be the value of the [[ProxyTarget]] internal slot of O. |
| 8231 Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate); |
| 8232 // 5. Let trap be ? GetMethod(handler, "ownKeys"). |
| 8233 Handle<Object> trap; |
| 8234 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 8235 isolate, trap, Object::GetMethod(Handle<JSReceiver>::cast(handler), |
| 8236 isolate->factory()->ownKeys_string()), |
| 8237 false); |
| 8238 // 6. If trap is undefined, then |
| 8239 if (trap->IsUndefined()) { |
| 8240 // 6a. Return target.[[OwnPropertyKeys]](). |
| 8241 return GetKeys_Internal(isolate, receiver, target, OWN_ONLY, filter, |
| 8242 enum_policy, accumulator); |
| 8243 } |
| 8244 // 7. Let trapResultArray be Call(trap, handler, «target»). |
| 8245 Handle<Object> trap_result_array; |
| 8246 Handle<Object> args[] = {target}; |
| 8247 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 8248 isolate, trap_result_array, |
| 8249 Execution::Call(isolate, trap, handler, arraysize(args), args), false); |
| 8250 // 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, |
| 8251 // «String, Symbol»). |
| 8252 Handle<FixedArray> trap_result; |
| 8253 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 8254 isolate, trap_result, |
| 8255 CreateListFromArrayLike_StringSymbol(isolate, trap_result_array), false); |
| 8256 // 9. Let extensibleTarget be ? IsExtensible(target). |
| 8257 Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target); |
| 8258 if (maybe_extensible.IsNothing()) return false; |
| 8259 bool extensible_target = maybe_extensible.FromJust(); |
| 8260 // 10. Let targetKeys be ? target.[[OwnPropertyKeys]](). |
| 8261 Handle<FixedArray> target_keys; |
| 8262 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 8263 isolate, target_keys, |
| 8264 JSReceiver::GetKeys(target, JSReceiver::OWN_ONLY, INCLUDE_SYMBOLS, |
| 8265 CONVERT_TO_STRING, IGNORE_ENUMERABILITY), |
| 8266 false); |
| 8267 // 11. (Assert) |
| 8268 // 12. Let targetConfigurableKeys be an empty List. |
| 8269 // To save memory, we're re-using target_keys and will modify it in-place. |
| 8270 Handle<FixedArray> target_configurable_keys = target_keys; |
| 8271 // 13. Let targetNonconfigurableKeys be an empty List. |
| 8272 Handle<FixedArray> target_nonconfigurable_keys = |
| 8273 isolate->factory()->NewFixedArray(target_keys->length()); |
| 8274 int nonconfigurable_keys_length = 0; |
| 8275 // 14. Repeat, for each element key of targetKeys: |
| 8276 for (int i = 0; i < target_keys->length(); ++i) { |
| 8277 // 14a. Let desc be ? target.[[GetOwnProperty]](key). |
| 8278 PropertyDescriptor desc; |
| 8279 bool found = JSReceiver::GetOwnPropertyDescriptor( |
| 8280 isolate, target, handle(target_keys->get(i), isolate), &desc); |
| 8281 if (isolate->has_pending_exception()) return false; |
| 8282 // 14b. If desc is not undefined and desc.[[Configurable]] is false, then |
| 8283 if (found && !desc.configurable()) { |
| 8284 // 14b i. Append key as an element of targetNonconfigurableKeys. |
| 8285 target_nonconfigurable_keys->set(nonconfigurable_keys_length, |
| 8286 target_keys->get(i)); |
| 8287 nonconfigurable_keys_length++; |
| 8288 // The key was moved, null it out in the original list. |
| 8289 target_keys->set(i, Smi::FromInt(0)); |
| 8290 } else { |
| 8291 // 14c. Else, |
| 8292 // 14c i. Append key as an element of targetConfigurableKeys. |
| 8293 // (No-op, just keep it in |target_keys|.) |
| 8294 } |
| 8295 } |
| 8296 accumulator->NextPrototype(); // Prepare for accumulating keys. |
| 8297 // 15. If extensibleTarget is true and targetNonconfigurableKeys is empty, |
| 8298 // then: |
| 8299 if (extensible_target && nonconfigurable_keys_length == 0) { |
| 8300 // 15a. Return trapResult. |
| 8301 accumulator->AddKeysFromProxy(trap_result); |
| 8302 return true; |
| 8303 } |
| 8304 // 16. Let uncheckedResultKeys be a new List which is a copy of trapResult. |
| 8305 Zone set_zone; |
| 8306 const int kPresent = 1; |
| 8307 const int kGone = 0; |
| 8308 IdentityMap<int> unchecked_result_keys(isolate->heap(), &set_zone); |
| 8309 int unchecked_result_keys_size = trap_result->length(); |
| 8310 for (int i = 0; i < trap_result->length(); ++i) { |
| 8311 DCHECK(trap_result->get(i)->IsUniqueName()); |
| 8312 unchecked_result_keys.Set(trap_result->get(i), kPresent); |
| 8313 } |
| 8314 // 17. Repeat, for each key that is an element of targetNonconfigurableKeys: |
| 8315 for (int i = 0; i < nonconfigurable_keys_length; ++i) { |
| 8316 Object* key = target_nonconfigurable_keys->get(i); |
| 8317 // 17a. If key is not an element of uncheckedResultKeys, throw a |
| 8318 // TypeError exception. |
| 8319 int* found = unchecked_result_keys.Find(key); |
| 8320 if (found == nullptr || *found == kGone) { |
| 8321 isolate->Throw(*isolate->factory()->NewTypeError( |
| 8322 MessageTemplate::kProxyTrapResultMustInclude, handle(key, isolate))); |
| 8323 return false; |
| 8324 } |
| 8325 // 17b. Remove key from uncheckedResultKeys. |
| 8326 *found = kGone; |
| 8327 unchecked_result_keys_size--; |
| 8328 } |
| 8329 // 18. If extensibleTarget is true, return trapResult. |
| 8330 if (extensible_target) { |
| 8331 accumulator->AddKeysFromProxy(trap_result); |
| 8332 return true; |
| 8333 } |
| 8334 // 19. Repeat, for each key that is an element of targetConfigurableKeys: |
| 8335 for (int i = 0; i < target_configurable_keys->length(); ++i) { |
| 8336 Object* key = target_configurable_keys->get(i); |
| 8337 if (key->IsSmi()) continue; // Zapped entry, was nonconfigurable. |
| 8338 // 19a. If key is not an element of uncheckedResultKeys, throw a |
| 8339 // TypeError exception. |
| 8340 int* found = unchecked_result_keys.Find(key); |
| 8341 if (found == nullptr || *found == kGone) { |
| 8342 isolate->Throw(*isolate->factory()->NewTypeError( |
| 8343 MessageTemplate::kProxyTrapResultMustInclude, handle(key, isolate))); |
| 8344 return false; |
| 8345 } |
| 8346 // 19b. Remove key from uncheckedResultKeys. |
| 8347 *found = kGone; |
| 8348 unchecked_result_keys_size--; |
| 8349 } |
| 8350 // 20. If uncheckedResultKeys is not empty, throw a TypeError exception. |
| 8351 if (unchecked_result_keys_size != 0) { |
| 8352 DCHECK_GT(unchecked_result_keys_size, 0); |
| 8353 isolate->Throw(*isolate->factory()->NewTypeError( |
| 8354 MessageTemplate::kProxyTargetNotExtensible)); |
| 8355 return false; |
| 8356 } |
| 8357 // 21. Return trapResult. |
| 8358 accumulator->AddKeysFromProxy(trap_result); |
| 8359 return true; |
| 8360 } |
| 8361 |
| 8362 |
8103 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, | 8363 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, |
8104 KeyCollectionType type, | 8364 KeyCollectionType type, |
8105 KeyFilter filter, | 8365 KeyFilter filter, |
8106 GetKeysConversion keys_conversion, | 8366 GetKeysConversion keys_conversion, |
8107 Enumerability enum_policy) { | 8367 Enumerability enum_policy) { |
8108 USE(ContainsOnlyValidKeys); | 8368 USE(ContainsOnlyValidKeys); |
8109 Isolate* isolate = object->GetIsolate(); | 8369 Isolate* isolate = object->GetIsolate(); |
8110 KeyAccumulator accumulator(isolate, filter); | 8370 KeyAccumulator accumulator(isolate, filter); |
8111 if (!GetKeys_Internal(isolate, object, object, type, filter, enum_policy, | 8371 if (!GetKeys_Internal(isolate, object, object, type, filter, enum_policy, |
8112 &accumulator)) { | 8372 &accumulator)) { |
8113 DCHECK(isolate->has_pending_exception()); | 8373 DCHECK(isolate->has_pending_exception()); |
8114 return MaybeHandle<FixedArray>(); | 8374 return MaybeHandle<FixedArray>(); |
8115 } | 8375 } |
8116 | |
8117 Handle<FixedArray> keys = accumulator.GetKeys(keys_conversion); | 8376 Handle<FixedArray> keys = accumulator.GetKeys(keys_conversion); |
8118 DCHECK(ContainsOnlyValidKeys(keys)); | 8377 DCHECK(ContainsOnlyValidKeys(keys)); |
8119 return keys; | 8378 return keys; |
8120 } | 8379 } |
8121 | 8380 |
8122 | 8381 |
8123 bool Map::DictionaryElementsInPrototypeChainOnly() { | 8382 bool Map::DictionaryElementsInPrototypeChainOnly() { |
8124 if (IsDictionaryElementsKind(elements_kind())) { | 8383 if (IsDictionaryElementsKind(elements_kind())) { |
8125 return false; | 8384 return false; |
8126 } | 8385 } |
(...skipping 10484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18611 if (cell->value() != *new_value) { | 18870 if (cell->value() != *new_value) { |
18612 cell->set_value(*new_value); | 18871 cell->set_value(*new_value); |
18613 Isolate* isolate = cell->GetIsolate(); | 18872 Isolate* isolate = cell->GetIsolate(); |
18614 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18873 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
18615 isolate, DependentCode::kPropertyCellChangedGroup); | 18874 isolate, DependentCode::kPropertyCellChangedGroup); |
18616 } | 18875 } |
18617 } | 18876 } |
18618 | 18877 |
18619 } // namespace internal | 18878 } // namespace internal |
18620 } // namespace v8 | 18879 } // namespace v8 |
OLD | NEW |