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" | |
32 #include "src/interpreter/bytecodes.h" | 31 #include "src/interpreter/bytecodes.h" |
33 #include "src/isolate-inl.h" | 32 #include "src/isolate-inl.h" |
34 #include "src/key-accumulator.h" | 33 #include "src/key-accumulator.h" |
35 #include "src/list.h" | 34 #include "src/list.h" |
36 #include "src/log.h" | 35 #include "src/log.h" |
37 #include "src/lookup.h" | 36 #include "src/lookup.h" |
38 #include "src/macro-assembler.h" | 37 #include "src/macro-assembler.h" |
39 #include "src/messages.h" | 38 #include "src/messages.h" |
40 #include "src/objects-inl.h" | 39 #include "src/objects-inl.h" |
41 #include "src/objects-body-descriptors-inl.h" | 40 #include "src/objects-body-descriptors-inl.h" |
42 #include "src/profiler/cpu-profiler.h" | 41 #include "src/profiler/cpu-profiler.h" |
43 #include "src/property-descriptor.h" | 42 #include "src/property-descriptor.h" |
44 #include "src/prototype.h" | 43 #include "src/prototype.h" |
45 #include "src/safepoint-table.h" | 44 #include "src/safepoint-table.h" |
46 #include "src/string-builder.h" | 45 #include "src/string-builder.h" |
47 #include "src/string-search.h" | 46 #include "src/string-search.h" |
48 #include "src/string-stream.h" | 47 #include "src/string-stream.h" |
49 #include "src/utils.h" | 48 #include "src/utils.h" |
50 #include "src/zone.h" | |
51 | 49 |
52 #ifdef ENABLE_DISASSEMBLER | 50 #ifdef ENABLE_DISASSEMBLER |
53 #include "src/disasm.h" | 51 #include "src/disasm.h" |
54 #include "src/disassembler.h" | 52 #include "src/disassembler.h" |
55 #endif | 53 #endif |
56 | 54 |
57 namespace v8 { | 55 namespace v8 { |
58 namespace internal { | 56 namespace internal { |
59 | 57 |
60 Handle<HeapType> Object::OptimalType(Isolate* isolate, | 58 Handle<HeapType> Object::OptimalType(Isolate* isolate, |
(...skipping 7925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7986 dictionary->CopyEnumKeysTo(*storage); | 7984 dictionary->CopyEnumKeysTo(*storage); |
7987 return storage; | 7985 return storage; |
7988 } | 7986 } |
7989 } | 7987 } |
7990 | 7988 |
7991 | 7989 |
7992 static bool GetKeysFromJSObject(Isolate* isolate, Handle<JSReceiver> receiver, | 7990 static bool GetKeysFromJSObject(Isolate* isolate, Handle<JSReceiver> receiver, |
7993 Handle<JSObject> object, KeyFilter filter, | 7991 Handle<JSObject> object, KeyFilter filter, |
7994 Enumerability enum_policy, | 7992 Enumerability enum_policy, |
7995 KeyAccumulator* accumulator) { | 7993 KeyAccumulator* accumulator) { |
7996 accumulator->NextPrototype(); | |
7997 // Check access rights if required. | 7994 // Check access rights if required. |
7998 if (object->IsAccessCheckNeeded() && | 7995 if (object->IsAccessCheckNeeded() && |
7999 !isolate->MayAccess(handle(isolate->context()), object)) { | 7996 !isolate->MayAccess(handle(isolate->context()), object)) { |
8000 // TODO(jkummerow): Get whitelisted (all-can-read) keys. | 7997 // TODO(jkummerow): Get whitelisted (all-can-read) keys. |
8001 // It's probably best to implement a "GetKeysWithFailedAccessCheck" | 7998 // It's probably best to implement a "GetKeysWithFailedAccessCheck" |
8002 // helper, which will need to look at both interceptors and accessors. | 7999 // helper, which will need to look at both interceptors and accessors. |
8003 return false; | 8000 return false; |
8004 } | 8001 } |
8005 | 8002 |
8006 PropertyAttributes attr_filter = static_cast<PropertyAttributes>( | 8003 PropertyAttributes attr_filter = static_cast<PropertyAttributes>( |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8066 Handle<JSReceiver> object, | 8063 Handle<JSReceiver> object, |
8067 JSReceiver::KeyCollectionType type, | 8064 JSReceiver::KeyCollectionType type, |
8068 KeyFilter filter, Enumerability enum_policy, | 8065 KeyFilter filter, Enumerability enum_policy, |
8069 KeyAccumulator* accumulator) { | 8066 KeyAccumulator* accumulator) { |
8070 PrototypeIterator::WhereToEnd end = type == JSReceiver::OWN_ONLY | 8067 PrototypeIterator::WhereToEnd end = type == JSReceiver::OWN_ONLY |
8071 ? PrototypeIterator::END_AT_NON_HIDDEN | 8068 ? PrototypeIterator::END_AT_NON_HIDDEN |
8072 : PrototypeIterator::END_AT_NULL; | 8069 : PrototypeIterator::END_AT_NULL; |
8073 for (PrototypeIterator iter(isolate, object, | 8070 for (PrototypeIterator iter(isolate, object, |
8074 PrototypeIterator::START_AT_RECEIVER); | 8071 PrototypeIterator::START_AT_RECEIVER); |
8075 !iter.IsAtEnd(end); iter.Advance()) { | 8072 !iter.IsAtEnd(end); iter.Advance()) { |
| 8073 accumulator->NextPrototype(); |
8076 Handle<JSReceiver> current = | 8074 Handle<JSReceiver> current = |
8077 PrototypeIterator::GetCurrent<JSReceiver>(iter); | 8075 PrototypeIterator::GetCurrent<JSReceiver>(iter); |
8078 bool result = false; | 8076 bool result = false; |
8079 if (current->IsJSProxy()) { | 8077 if (current->IsJSProxy()) { |
8080 if (type == JSReceiver::OWN_ONLY) { | 8078 Handle<Object> args[] = {current}; |
8081 result = JSProxy::OwnPropertyKeys(isolate, receiver, | 8079 Handle<Object> names; |
8082 Handle<JSProxy>::cast(current), | 8080 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
8083 filter, enum_policy, accumulator); | 8081 isolate, names, Execution::Call(isolate, isolate->proxy_enumerate(), |
8084 } else { | 8082 current, arraysize(args), args), |
8085 DCHECK(type == JSReceiver::INCLUDE_PROTOS); | 8083 false); |
8086 result = JSProxy::Enumerate( | 8084 accumulator->AddKeysFromProxy(Handle<JSObject>::cast(names)); |
8087 isolate, receiver, Handle<JSProxy>::cast(current), accumulator); | |
8088 } | |
8089 } else { | 8085 } else { |
8090 DCHECK(current->IsJSObject()); | 8086 DCHECK(current->IsJSObject()); |
8091 result = GetKeysFromJSObject(isolate, receiver, | 8087 result = GetKeysFromJSObject(isolate, receiver, |
8092 Handle<JSObject>::cast(current), filter, | 8088 Handle<JSObject>::cast(current), filter, |
8093 enum_policy, accumulator); | 8089 enum_policy, accumulator); |
8094 } | 8090 } |
8095 if (!result) { | 8091 if (!result) { |
8096 if (isolate->has_pending_exception()) { | 8092 if (isolate->has_pending_exception()) { |
8097 return false; | 8093 return false; |
8098 } | 8094 } |
8099 // If there was no exception, then "false" means "stop iterating". | 8095 // If there was no exception, then "false" means "stop iterating". |
8100 break; | 8096 break; |
8101 } | 8097 } |
8102 } | 8098 } |
8103 return true; | 8099 return true; |
8104 } | 8100 } |
8105 | 8101 |
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 list->set(index, | |
8204 *isolate->factory()->InternalizeName(Handle<Name>::cast(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 | 8102 |
8363 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, | 8103 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, |
8364 KeyCollectionType type, | 8104 KeyCollectionType type, |
8365 KeyFilter filter, | 8105 KeyFilter filter, |
8366 GetKeysConversion keys_conversion, | 8106 GetKeysConversion keys_conversion, |
8367 Enumerability enum_policy) { | 8107 Enumerability enum_policy) { |
8368 USE(ContainsOnlyValidKeys); | 8108 USE(ContainsOnlyValidKeys); |
8369 Isolate* isolate = object->GetIsolate(); | 8109 Isolate* isolate = object->GetIsolate(); |
8370 KeyAccumulator accumulator(isolate, filter); | 8110 KeyAccumulator accumulator(isolate, filter); |
8371 if (!GetKeys_Internal(isolate, object, object, type, filter, enum_policy, | 8111 if (!GetKeys_Internal(isolate, object, object, type, filter, enum_policy, |
8372 &accumulator)) { | 8112 &accumulator)) { |
8373 DCHECK(isolate->has_pending_exception()); | 8113 DCHECK(isolate->has_pending_exception()); |
8374 return MaybeHandle<FixedArray>(); | 8114 return MaybeHandle<FixedArray>(); |
8375 } | 8115 } |
| 8116 |
8376 Handle<FixedArray> keys = accumulator.GetKeys(keys_conversion); | 8117 Handle<FixedArray> keys = accumulator.GetKeys(keys_conversion); |
8377 DCHECK(ContainsOnlyValidKeys(keys)); | 8118 DCHECK(ContainsOnlyValidKeys(keys)); |
8378 return keys; | 8119 return keys; |
8379 } | 8120 } |
8380 | 8121 |
8381 | 8122 |
8382 bool Map::DictionaryElementsInPrototypeChainOnly() { | 8123 bool Map::DictionaryElementsInPrototypeChainOnly() { |
8383 if (IsDictionaryElementsKind(elements_kind())) { | 8124 if (IsDictionaryElementsKind(elements_kind())) { |
8384 return false; | 8125 return false; |
8385 } | 8126 } |
(...skipping 10484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18870 if (cell->value() != *new_value) { | 18611 if (cell->value() != *new_value) { |
18871 cell->set_value(*new_value); | 18612 cell->set_value(*new_value); |
18872 Isolate* isolate = cell->GetIsolate(); | 18613 Isolate* isolate = cell->GetIsolate(); |
18873 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18614 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
18874 isolate, DependentCode::kPropertyCellChangedGroup); | 18615 isolate, DependentCode::kPropertyCellChangedGroup); |
18875 } | 18616 } |
18876 } | 18617 } |
18877 | 18618 |
18878 } // namespace internal | 18619 } // namespace internal |
18879 } // namespace v8 | 18620 } // namespace v8 |
OLD | NEW |