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 "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 4768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4779 } | 4779 } |
| 4780 | 4780 |
| 4781 return JSObject::GetFunctionRealm(Handle<JSObject>::cast(receiver)); | 4781 return JSObject::GetFunctionRealm(Handle<JSObject>::cast(receiver)); |
| 4782 } | 4782 } |
| 4783 | 4783 |
| 4784 | 4784 |
| 4785 Maybe<PropertyAttributes> JSProxy::GetPropertyAttributes(LookupIterator* it) { | 4785 Maybe<PropertyAttributes> JSProxy::GetPropertyAttributes(LookupIterator* it) { |
| 4786 Isolate* isolate = it->isolate(); | 4786 Isolate* isolate = it->isolate(); |
| 4787 HandleScope scope(isolate); | 4787 HandleScope scope(isolate); |
| 4788 PropertyDescriptor desc; | 4788 PropertyDescriptor desc; |
| 4789 bool found = JSProxy::GetOwnPropertyDescriptor(it, &desc); | 4789 bool found = JSProxy::GetOwnPropertyDescriptor( |
| 4790 isolate, it->GetHolder<JSProxy>(), it->GetName(), &desc); | |
| 4790 if (isolate->has_pending_exception()) return Nothing<PropertyAttributes>(); | 4791 if (isolate->has_pending_exception()) return Nothing<PropertyAttributes>(); |
| 4791 if (!found) return Just(ABSENT); | 4792 if (!found) return Just(ABSENT); |
| 4792 return Just(desc.ToAttributes()); | 4793 return Just(desc.ToAttributes()); |
| 4793 } | 4794 } |
| 4794 | 4795 |
| 4795 | 4796 |
| 4796 MaybeHandle<Object> JSProxy::GetTrap(Handle<JSProxy> proxy, | 4797 MaybeHandle<Object> JSProxy::GetTrap(Handle<JSProxy> proxy, |
| 4797 Handle<String> trap) { | 4798 Handle<String> trap) { |
| 4798 DCHECK(!proxy->IsRevoked()); | 4799 DCHECK(!proxy->IsRevoked()); |
| 4799 Isolate* isolate = proxy->GetIsolate(); | 4800 Isolate* isolate = proxy->GetIsolate(); |
| (...skipping 2093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6893 | 6894 |
| 6894 | 6895 |
| 6895 // TODO(jkummerow): Any chance to unify this with | 6896 // TODO(jkummerow): Any chance to unify this with |
| 6896 // "MaybeHandle<Object> GetOwnProperty()" in runtime-object.cc? | 6897 // "MaybeHandle<Object> GetOwnProperty()" in runtime-object.cc? |
| 6897 | 6898 |
| 6898 // ES6 9.1.5.1 | 6899 // ES6 9.1.5.1 |
| 6899 // Returns true on success; false if there was an exception or no property. | 6900 // Returns true on success; false if there was an exception or no property. |
| 6900 // static | 6901 // static |
| 6901 bool JSReceiver::GetOwnPropertyDescriptor(LookupIterator* it, | 6902 bool JSReceiver::GetOwnPropertyDescriptor(LookupIterator* it, |
| 6902 PropertyDescriptor* desc) { | 6903 PropertyDescriptor* desc) { |
| 6904 Isolate* isolate = it->isolate(); | |
| 6903 // "Virtual" dispatch. | 6905 // "Virtual" dispatch. |
| 6904 if (it->IsFound() && it->GetHolder<JSReceiver>()->IsJSProxy()) { | 6906 if (it->IsFound() && it->GetHolder<JSReceiver>()->IsJSProxy()) { |
| 6905 return JSProxy::GetOwnPropertyDescriptor(it, desc); | 6907 return JSProxy::GetOwnPropertyDescriptor(isolate, it->GetHolder<JSProxy>(), |
| 6908 it->GetName(), desc); | |
| 6906 } | 6909 } |
| 6907 | 6910 |
| 6908 Isolate* isolate = it->isolate(); | |
| 6909 // 1. (Assert) | 6911 // 1. (Assert) |
| 6910 // 2. If O does not have an own property with key P, return undefined. | 6912 // 2. If O does not have an own property with key P, return undefined. |
| 6911 Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(it); | 6913 Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(it); |
| 6912 | 6914 |
| 6913 if (!maybe.IsJust()) return false; | 6915 if (!maybe.IsJust()) return false; |
| 6914 PropertyAttributes attrs = maybe.FromJust(); | 6916 PropertyAttributes attrs = maybe.FromJust(); |
| 6915 if (attrs == ABSENT) return false; | 6917 if (attrs == ABSENT) return false; |
| 6916 DCHECK(!isolate->has_pending_exception()); | 6918 DCHECK(!isolate->has_pending_exception()); |
| 6917 | 6919 |
| 6918 // 3. Let D be a newly created Property Descriptor with no fields. | 6920 // 3. Let D be a newly created Property Descriptor with no fields. |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 6947 desc->set_configurable((attrs & DONT_DELETE) == 0); | 6949 desc->set_configurable((attrs & DONT_DELETE) == 0); |
| 6948 // 9. Return D. | 6950 // 9. Return D. |
| 6949 DCHECK(PropertyDescriptor::IsAccessorDescriptor(desc) != | 6951 DCHECK(PropertyDescriptor::IsAccessorDescriptor(desc) != |
| 6950 PropertyDescriptor::IsDataDescriptor(desc)); | 6952 PropertyDescriptor::IsDataDescriptor(desc)); |
| 6951 return true; | 6953 return true; |
| 6952 } | 6954 } |
| 6953 | 6955 |
| 6954 | 6956 |
| 6955 // ES6 9.5.5 | 6957 // ES6 9.5.5 |
| 6956 // static | 6958 // static |
| 6957 bool JSProxy::GetOwnPropertyDescriptor(LookupIterator* it, | 6959 bool JSProxy::GetOwnPropertyDescriptor(Isolate* isolate, Handle<JSProxy> proxy, |
| 6960 Handle<Name> name, | |
| 6958 PropertyDescriptor* desc) { | 6961 PropertyDescriptor* desc) { |
| 6959 Handle<JSProxy> proxy = it->GetHolder<JSProxy>(); | |
| 6960 Isolate* isolate = it->isolate(); | |
| 6961 Handle<String> trap_name = | 6962 Handle<String> trap_name = |
| 6962 isolate->factory()->getOwnPropertyDescriptor_string(); | 6963 isolate->factory()->getOwnPropertyDescriptor_string(); |
| 6963 Handle<Name> property_name = it->GetName(); | |
| 6964 // 1. (Assert) | 6964 // 1. (Assert) |
| 6965 // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. | 6965 // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. |
| 6966 Handle<Object> handler(proxy->handler(), isolate); | 6966 Handle<Object> handler(proxy->handler(), isolate); |
| 6967 // 3. If handler is null, throw a TypeError exception. | 6967 // 3. If handler is null, throw a TypeError exception. |
| 6968 if (proxy->IsRevoked()) { | 6968 if (proxy->IsRevoked()) { |
| 6969 isolate->Throw(*isolate->factory()->NewTypeError( | 6969 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6970 MessageTemplate::kProxyRevoked, trap_name)); | 6970 MessageTemplate::kProxyRevoked, trap_name)); |
| 6971 return false; | 6971 return false; |
| 6972 } | 6972 } |
| 6973 // 4. Assert: Type(handler) is Object. | 6973 // 4. Assert: Type(handler) is Object. |
| 6974 DCHECK(handler->IsJSReceiver()); | 6974 DCHECK(handler->IsJSReceiver()); |
| 6975 // If the handler is not null, the target can't be null either. | 6975 // If the handler is not null, the target can't be null either. |
| 6976 DCHECK(it->GetHolder<JSProxy>()->target()->IsJSReceiver()); | 6976 DCHECK(proxy->target()->IsJSReceiver()); |
| 6977 // 5. Let target be the value of the [[ProxyTarget]] internal slot of O. | 6977 // 5. Let target be the value of the [[ProxyTarget]] internal slot of O. |
| 6978 Handle<JSReceiver> target( | 6978 Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate); |
| 6979 JSReceiver::cast(it->GetHolder<JSProxy>()->target()), isolate); | |
| 6980 // 6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor"). | 6979 // 6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor"). |
| 6981 Handle<Object> trap; | 6980 Handle<Object> trap; |
| 6982 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 6981 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 6983 isolate, trap, | 6982 isolate, trap, |
| 6984 Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name), false); | 6983 Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name), false); |
| 6985 // 7. If trap is undefined, then | 6984 // 7. If trap is undefined, then |
| 6986 if (trap->IsUndefined()) { | 6985 if (trap->IsUndefined()) { |
| 6987 // 7a. Return target.[[GetOwnProperty]](P). | 6986 // 7a. Return target.[[GetOwnProperty]](P). |
| 6988 return JSReceiver::GetOwnPropertyDescriptor(isolate, target, property_name, | 6987 return JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, desc); |
| 6989 desc); | |
| 6990 } | 6988 } |
| 6991 // 8. Let trapResultObj be ? Call(trap, handler, «target, P»). | 6989 // 8. Let trapResultObj be ? Call(trap, handler, «target, P»). |
| 6992 Handle<Object> trap_result_obj; | 6990 Handle<Object> trap_result_obj; |
| 6993 Handle<Object> args[] = {target, property_name}; | 6991 Handle<Object> args[] = {target, name}; |
| 6994 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 6992 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 6995 isolate, trap_result_obj, | 6993 isolate, trap_result_obj, |
| 6996 Execution::Call(isolate, trap, handler, arraysize(args), args), false); | 6994 Execution::Call(isolate, trap, handler, arraysize(args), args), false); |
| 6997 // 9. If Type(trapResultObj) is neither Object nor Undefined, throw a | 6995 // 9. If Type(trapResultObj) is neither Object nor Undefined, throw a |
| 6998 // TypeError exception. | 6996 // TypeError exception. |
| 6999 if (!trap_result_obj->IsJSReceiver() && !trap_result_obj->IsUndefined()) { | 6997 if (!trap_result_obj->IsJSReceiver() && !trap_result_obj->IsUndefined()) { |
| 7000 isolate->Throw(*isolate->factory()->NewTypeError( | 6998 isolate->Throw(*isolate->factory()->NewTypeError( |
| 7001 MessageTemplate::kProxyHandlerReturned, handler, trap_result_obj, | 6999 MessageTemplate::kProxyHandlerReturned, handler, trap_result_obj, |
| 7002 property_name)); | 7000 name)); |
| 7003 return false; | 7001 return false; |
| 7004 } | 7002 } |
| 7005 // 10. Let targetDesc be ? target.[[GetOwnProperty]](P). | 7003 // 10. Let targetDesc be ? target.[[GetOwnProperty]](P). |
| 7006 PropertyDescriptor target_desc; | 7004 PropertyDescriptor target_desc; |
| 7007 JSReceiver::GetOwnPropertyDescriptor(isolate, target, property_name, | 7005 JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc); |
| 7008 &target_desc); | |
| 7009 if (isolate->has_pending_exception()) return false; | 7006 if (isolate->has_pending_exception()) return false; |
| 7010 // 11. If trapResultObj is undefined, then | 7007 // 11. If trapResultObj is undefined, then |
| 7011 if (trap_result_obj->IsUndefined()) { | 7008 if (trap_result_obj->IsUndefined()) { |
| 7012 // 11a. If targetDesc is undefined, return undefined. | 7009 // 11a. If targetDesc is undefined, return undefined. |
| 7013 if (target_desc.is_empty()) return false; | 7010 if (target_desc.is_empty()) return false; |
| 7014 // 11b. If targetDesc.[[Configurable]] is false, throw a TypeError | 7011 // 11b. If targetDesc.[[Configurable]] is false, throw a TypeError |
| 7015 // exception. | 7012 // exception. |
| 7016 if (!target_desc.configurable()) { | 7013 if (!target_desc.configurable()) { |
| 7017 isolate->Throw(*isolate->factory()->NewTypeError( | 7014 isolate->Throw(*isolate->factory()->NewTypeError( |
| 7018 MessageTemplate::kProxyTargetPropNotConfigurable, property_name)); | 7015 MessageTemplate::kProxyTargetPropNotConfigurable, name)); |
| 7019 return false; | 7016 return false; |
| 7020 } | 7017 } |
| 7021 // 11c. Let extensibleTarget be ? IsExtensible(target). | 7018 // 11c. Let extensibleTarget be ? IsExtensible(target). |
| 7022 Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target); | 7019 Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target); |
| 7023 if (maybe_extensible.IsNothing()) return false; | 7020 if (maybe_extensible.IsNothing()) return false; |
| 7024 bool extensible_target = maybe_extensible.FromJust(); | 7021 bool extensible_target = maybe_extensible.FromJust(); |
| 7025 // 11d. (Assert) | 7022 // 11d. (Assert) |
| 7026 // 11e. If extensibleTarget is false, throw a TypeError exception. | 7023 // 11e. If extensibleTarget is false, throw a TypeError exception. |
| 7027 if (!extensible_target) { | 7024 if (!extensible_target) { |
| 7028 isolate->Throw(*isolate->factory()->NewTypeError( | 7025 isolate->Throw(*isolate->factory()->NewTypeError( |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 7040 if (!PropertyDescriptor::ToPropertyDescriptor(isolate, trap_result_obj, | 7037 if (!PropertyDescriptor::ToPropertyDescriptor(isolate, trap_result_obj, |
| 7041 desc)) { | 7038 desc)) { |
| 7042 DCHECK(isolate->has_pending_exception()); | 7039 DCHECK(isolate->has_pending_exception()); |
| 7043 return false; | 7040 return false; |
| 7044 } | 7041 } |
| 7045 // 14. Call CompletePropertyDescriptor(resultDesc). | 7042 // 14. Call CompletePropertyDescriptor(resultDesc). |
| 7046 PropertyDescriptor::CompletePropertyDescriptor(isolate, desc); | 7043 PropertyDescriptor::CompletePropertyDescriptor(isolate, desc); |
| 7047 // 15. Let valid be IsCompatiblePropertyDescriptor (extensibleTarget, | 7044 // 15. Let valid be IsCompatiblePropertyDescriptor (extensibleTarget, |
| 7048 // resultDesc, targetDesc). | 7045 // resultDesc, targetDesc). |
| 7049 bool valid = IsCompatiblePropertyDescriptor(isolate, extensible_target, desc, | 7046 bool valid = IsCompatiblePropertyDescriptor(isolate, extensible_target, desc, |
| 7050 &target_desc, property_name); | 7047 &target_desc, name); |
| 7051 // 16. If valid is false, throw a TypeError exception. | 7048 // 16. If valid is false, throw a TypeError exception. |
| 7052 if (!valid) { | 7049 if (!valid) { |
| 7053 DCHECK(isolate->has_pending_exception()); | 7050 DCHECK(isolate->has_pending_exception()); |
| 7054 return false; | 7051 return false; |
| 7055 } | 7052 } |
| 7056 // 17. If resultDesc.[[Configurable]] is false, then | 7053 // 17. If resultDesc.[[Configurable]] is false, then |
| 7057 if (!desc->configurable()) { | 7054 if (!desc->configurable()) { |
| 7058 // 17a. If targetDesc is undefined or targetDesc.[[Configurable]] is true: | 7055 // 17a. If targetDesc is undefined or targetDesc.[[Configurable]] is true: |
| 7059 if (target_desc.is_empty() || target_desc.configurable()) { | 7056 if (target_desc.is_empty() || target_desc.configurable()) { |
| 7060 // 17a i. Throw a TypeError exception. | 7057 // 17a i. Throw a TypeError exception. |
| 7061 isolate->Throw(*isolate->factory()->NewTypeError( | 7058 isolate->Throw(*isolate->factory()->NewTypeError( |
| 7062 MessageTemplate::kRedefineDisallowed, property_name)); | 7059 MessageTemplate::kRedefineDisallowed, name)); |
| 7063 return false; | 7060 return false; |
| 7064 } | 7061 } |
| 7065 } | 7062 } |
| 7066 // 18. Return resultDesc. | 7063 // 18. Return resultDesc. |
| 7067 return true; | 7064 return true; |
| 7068 } | 7065 } |
| 7069 | 7066 |
| 7070 | 7067 |
| 7071 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, | 7068 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, |
| 7072 ElementsKind kind, | 7069 ElementsKind kind, |
| (...skipping 1213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8286 // Internalize on the fly so we can use pointer identity later. | 8283 // Internalize on the fly so we can use pointer identity later. |
| 8287 next = isolate->factory()->InternalizeName(Handle<Name>::cast(next)); | 8284 next = isolate->factory()->InternalizeName(Handle<Name>::cast(next)); |
| 8288 list->set(index, *next); | 8285 list->set(index, *next); |
| 8289 // 7e. Set index to index + 1. (See loop header.) | 8286 // 7e. Set index to index + 1. (See loop header.) |
| 8290 } | 8287 } |
| 8291 // 8. Return list. | 8288 // 8. Return list. |
| 8292 return list; | 8289 return list; |
| 8293 } | 8290 } |
| 8294 | 8291 |
| 8295 | 8292 |
| 8293 MaybeHandle<FixedArray> FilterProxyKeys(Isolate* isolate, Handle<JSProxy> owner, | |
| 8294 Handle<FixedArray> keys, | |
| 8295 KeyFilter filter, | |
| 8296 Enumerability enum_policy) { | |
| 8297 if (filter == INCLUDE_SYMBOLS && enum_policy == IGNORE_ENUMERABILITY) { | |
| 8298 // Nothing to do. | |
| 8299 return keys; | |
| 8300 } | |
| 8301 int store_position = 0; | |
| 8302 for (int i = 0; i < keys->length(); ++i) { | |
| 8303 Handle<Name> key(Name::cast(keys->get(i)), isolate); | |
| 8304 if (filter == SKIP_SYMBOLS && key->IsSymbol()) continue; // Skip this key. | |
| 8305 if (enum_policy == RESPECT_ENUMERABILITY) { | |
| 8306 PropertyDescriptor desc; | |
| 8307 bool found = | |
| 8308 JSProxy::GetOwnPropertyDescriptor(isolate, owner, key, &desc); | |
| 8309 if (isolate->has_pending_exception()) return MaybeHandle<FixedArray>(); | |
| 8310 if (!found || !desc.enumerable()) continue; // Skip this key. | |
| 8311 } | |
| 8312 // Keep this key. | |
| 8313 if (store_position != i) { | |
| 8314 keys->set(store_position, *key); | |
| 8315 } | |
| 8316 store_position++; | |
| 8317 } | |
| 8318 if (store_position == 0) return isolate->factory()->empty_fixed_array(); | |
| 8319 keys->Shrink(store_position); | |
|
Camillo Bruni
2015/12/01 14:39:39
we could actually avoid shrinking it by passing th
Jakob Kummerow
2015/12/02 09:42:56
Acknowledged.
| |
| 8320 return keys; | |
| 8321 } | |
| 8322 | |
| 8323 | |
| 8296 // ES6 9.5.12 | 8324 // ES6 9.5.12 |
| 8297 // Returns "false" in case of exception. | 8325 // Returns "false" in case of exception. |
| 8298 // TODO(jkummerow): |filter| and |enum_policy| are currently ignored. | |
| 8299 // static | 8326 // static |
| 8300 bool JSProxy::OwnPropertyKeys(Isolate* isolate, Handle<JSReceiver> receiver, | 8327 bool JSProxy::OwnPropertyKeys(Isolate* isolate, Handle<JSReceiver> receiver, |
| 8301 Handle<JSProxy> proxy, KeyFilter filter, | 8328 Handle<JSProxy> proxy, KeyFilter filter, |
| 8302 Enumerability enum_policy, | 8329 Enumerability enum_policy, |
| 8303 KeyAccumulator* accumulator) { | 8330 KeyAccumulator* accumulator) { |
| 8304 // 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. | 8331 // 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. |
| 8305 Handle<Object> handler(proxy->handler(), isolate); | 8332 Handle<Object> handler(proxy->handler(), isolate); |
| 8306 // 2. If handler is null, throw a TypeError exception. | 8333 // 2. If handler is null, throw a TypeError exception. |
| 8307 if (proxy->IsRevoked()) { | 8334 if (proxy->IsRevoked()) { |
| 8308 isolate->Throw(*isolate->factory()->NewTypeError( | 8335 isolate->Throw(*isolate->factory()->NewTypeError( |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8363 bool found = JSReceiver::GetOwnPropertyDescriptor( | 8390 bool found = JSReceiver::GetOwnPropertyDescriptor( |
| 8364 isolate, target, handle(target_keys->get(i), isolate), &desc); | 8391 isolate, target, handle(target_keys->get(i), isolate), &desc); |
| 8365 if (isolate->has_pending_exception()) return false; | 8392 if (isolate->has_pending_exception()) return false; |
| 8366 // 14b. If desc is not undefined and desc.[[Configurable]] is false, then | 8393 // 14b. If desc is not undefined and desc.[[Configurable]] is false, then |
| 8367 if (found && !desc.configurable()) { | 8394 if (found && !desc.configurable()) { |
| 8368 // 14b i. Append key as an element of targetNonconfigurableKeys. | 8395 // 14b i. Append key as an element of targetNonconfigurableKeys. |
| 8369 target_nonconfigurable_keys->set(nonconfigurable_keys_length, | 8396 target_nonconfigurable_keys->set(nonconfigurable_keys_length, |
| 8370 target_keys->get(i)); | 8397 target_keys->get(i)); |
| 8371 nonconfigurable_keys_length++; | 8398 nonconfigurable_keys_length++; |
| 8372 // The key was moved, null it out in the original list. | 8399 // The key was moved, null it out in the original list. |
| 8373 target_keys->set(i, Smi::FromInt(0)); | 8400 target_keys->set(i, Smi::FromInt(0)); |
|
Camillo Bruni
2015/12/01 14:39:39
I'd prefer working on target_configurable_keys ins
Jakob Kummerow
2015/12/02 09:42:56
As discussed, I disagree. At this point we're iter
| |
| 8374 } else { | 8401 } else { |
| 8375 // 14c. Else, | 8402 // 14c. Else, |
| 8376 // 14c i. Append key as an element of targetConfigurableKeys. | 8403 // 14c i. Append key as an element of targetConfigurableKeys. |
| 8377 // (No-op, just keep it in |target_keys|.) | 8404 // (No-op, just keep it in |target_keys|.) |
| 8378 } | 8405 } |
| 8379 } | 8406 } |
| 8380 accumulator->NextPrototype(); // Prepare for accumulating keys. | 8407 accumulator->NextPrototype(); // Prepare for accumulating keys. |
| 8381 // 15. If extensibleTarget is true and targetNonconfigurableKeys is empty, | 8408 // 15. If extensibleTarget is true and targetNonconfigurableKeys is empty, |
| 8382 // then: | 8409 // then: |
| 8383 if (extensible_target && nonconfigurable_keys_length == 0) { | 8410 if (extensible_target && nonconfigurable_keys_length == 0) { |
| 8384 // 15a. Return trapResult. | 8411 // 15a. Return trapResult. |
| 8412 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
| 8413 isolate, trap_result, | |
| 8414 FilterProxyKeys(isolate, proxy, trap_result, filter, enum_policy), | |
| 8415 false); | |
|
Camillo Bruni
2015/12/01 14:39:39
I wonder whether it would not make more sense to d
Jakob Kummerow
2015/12/02 09:42:56
Done -- moved it into the AddKeysFromProxy call ri
| |
| 8385 accumulator->AddKeysFromProxy(trap_result); | 8416 accumulator->AddKeysFromProxy(trap_result); |
| 8386 return true; | 8417 return true; |
| 8387 } | 8418 } |
| 8388 // 16. Let uncheckedResultKeys be a new List which is a copy of trapResult. | 8419 // 16. Let uncheckedResultKeys be a new List which is a copy of trapResult. |
| 8389 Zone set_zone; | 8420 Zone set_zone; |
| 8390 const int kPresent = 1; | 8421 const int kPresent = 1; |
| 8391 const int kGone = 0; | 8422 const int kGone = 0; |
| 8392 IdentityMap<int> unchecked_result_keys(isolate->heap(), &set_zone); | 8423 IdentityMap<int> unchecked_result_keys(isolate->heap(), &set_zone); |
| 8393 int unchecked_result_keys_size = trap_result->length(); | 8424 int unchecked_result_keys_size = trap_result->length(); |
| 8394 for (int i = 0; i < trap_result->length(); ++i) { | 8425 for (int i = 0; i < trap_result->length(); ++i) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 8405 isolate->Throw(*isolate->factory()->NewTypeError( | 8436 isolate->Throw(*isolate->factory()->NewTypeError( |
| 8406 MessageTemplate::kProxyTrapResultMustInclude, handle(key, isolate))); | 8437 MessageTemplate::kProxyTrapResultMustInclude, handle(key, isolate))); |
| 8407 return false; | 8438 return false; |
| 8408 } | 8439 } |
| 8409 // 17b. Remove key from uncheckedResultKeys. | 8440 // 17b. Remove key from uncheckedResultKeys. |
| 8410 *found = kGone; | 8441 *found = kGone; |
| 8411 unchecked_result_keys_size--; | 8442 unchecked_result_keys_size--; |
| 8412 } | 8443 } |
| 8413 // 18. If extensibleTarget is true, return trapResult. | 8444 // 18. If extensibleTarget is true, return trapResult. |
| 8414 if (extensible_target) { | 8445 if (extensible_target) { |
| 8446 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
| 8447 isolate, trap_result, | |
| 8448 FilterProxyKeys(isolate, proxy, trap_result, filter, enum_policy), | |
| 8449 false); | |
| 8415 accumulator->AddKeysFromProxy(trap_result); | 8450 accumulator->AddKeysFromProxy(trap_result); |
| 8416 return true; | 8451 return true; |
| 8417 } | 8452 } |
| 8418 // 19. Repeat, for each key that is an element of targetConfigurableKeys: | 8453 // 19. Repeat, for each key that is an element of targetConfigurableKeys: |
| 8419 for (int i = 0; i < target_configurable_keys->length(); ++i) { | 8454 for (int i = 0; i < target_configurable_keys->length(); ++i) { |
| 8420 Object* key = target_configurable_keys->get(i); | 8455 Object* key = target_configurable_keys->get(i); |
| 8421 if (key->IsSmi()) continue; // Zapped entry, was nonconfigurable. | 8456 if (key->IsSmi()) continue; // Zapped entry, was nonconfigurable. |
| 8422 // 19a. If key is not an element of uncheckedResultKeys, throw a | 8457 // 19a. If key is not an element of uncheckedResultKeys, throw a |
| 8423 // TypeError exception. | 8458 // TypeError exception. |
| 8424 int* found = unchecked_result_keys.Find(key); | 8459 int* found = unchecked_result_keys.Find(key); |
| 8425 if (found == nullptr || *found == kGone) { | 8460 if (found == nullptr || *found == kGone) { |
| 8426 isolate->Throw(*isolate->factory()->NewTypeError( | 8461 isolate->Throw(*isolate->factory()->NewTypeError( |
| 8427 MessageTemplate::kProxyTrapResultMustInclude, handle(key, isolate))); | 8462 MessageTemplate::kProxyTrapResultMustInclude, handle(key, isolate))); |
| 8428 return false; | 8463 return false; |
| 8429 } | 8464 } |
| 8430 // 19b. Remove key from uncheckedResultKeys. | 8465 // 19b. Remove key from uncheckedResultKeys. |
| 8431 *found = kGone; | 8466 *found = kGone; |
| 8432 unchecked_result_keys_size--; | 8467 unchecked_result_keys_size--; |
| 8433 } | 8468 } |
| 8434 // 20. If uncheckedResultKeys is not empty, throw a TypeError exception. | 8469 // 20. If uncheckedResultKeys is not empty, throw a TypeError exception. |
| 8435 if (unchecked_result_keys_size != 0) { | 8470 if (unchecked_result_keys_size != 0) { |
| 8436 DCHECK_GT(unchecked_result_keys_size, 0); | 8471 DCHECK_GT(unchecked_result_keys_size, 0); |
| 8437 isolate->Throw(*isolate->factory()->NewTypeError( | 8472 isolate->Throw(*isolate->factory()->NewTypeError( |
| 8438 MessageTemplate::kProxyTargetNotExtensible)); | 8473 MessageTemplate::kProxyTargetNotExtensible)); |
| 8439 return false; | 8474 return false; |
| 8440 } | 8475 } |
| 8441 // 21. Return trapResult. | 8476 // 21. Return trapResult. |
| 8477 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
| 8478 isolate, trap_result, | |
| 8479 FilterProxyKeys(isolate, proxy, trap_result, filter, enum_policy), false); | |
| 8442 accumulator->AddKeysFromProxy(trap_result); | 8480 accumulator->AddKeysFromProxy(trap_result); |
| 8443 return true; | 8481 return true; |
| 8444 } | 8482 } |
| 8445 | 8483 |
| 8446 | 8484 |
| 8447 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, | 8485 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, |
| 8448 KeyCollectionType type, | 8486 KeyCollectionType type, |
| 8449 KeyFilter filter, | 8487 KeyFilter filter, |
| 8450 GetKeysConversion keys_conversion, | 8488 GetKeysConversion keys_conversion, |
| 8451 Enumerability enum_policy) { | 8489 Enumerability enum_policy) { |
| (...skipping 10526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 18978 if (cell->value() != *new_value) { | 19016 if (cell->value() != *new_value) { |
| 18979 cell->set_value(*new_value); | 19017 cell->set_value(*new_value); |
| 18980 Isolate* isolate = cell->GetIsolate(); | 19018 Isolate* isolate = cell->GetIsolate(); |
| 18981 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19019 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 18982 isolate, DependentCode::kPropertyCellChangedGroup); | 19020 isolate, DependentCode::kPropertyCellChangedGroup); |
| 18983 } | 19021 } |
| 18984 } | 19022 } |
| 18985 | 19023 |
| 18986 } // namespace internal | 19024 } // namespace internal |
| 18987 } // namespace v8 | 19025 } // namespace v8 |
| OLD | NEW |