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 4706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4717 } | 4717 } |
| 4718 | 4718 |
| 4719 Handle<Object> trap_result; | 4719 Handle<Object> trap_result; |
| 4720 Handle<Object> args[] = {target, name, value, receiver}; | 4720 Handle<Object> args[] = {target, name, value, receiver}; |
| 4721 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 4721 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 4722 isolate, trap_result, | 4722 isolate, trap_result, |
| 4723 Execution::Call(isolate, trap, handler, arraysize(args), args), | 4723 Execution::Call(isolate, trap, handler, arraysize(args), args), |
| 4724 Nothing<bool>()); | 4724 Nothing<bool>()); |
| 4725 if (!trap_result->BooleanValue()) { | 4725 if (!trap_result->BooleanValue()) { |
| 4726 RETURN_FAILURE(isolate, should_throw, | 4726 RETURN_FAILURE(isolate, should_throw, |
| 4727 NewTypeError(MessageTemplate::kProxyHandlerReturned, handler, | 4727 NewTypeError(MessageTemplate::kProxyTrapReturnedNonBoolean, |
|
Jakob Kummerow
2015/12/10 15:35:03
Nope, the problem is that it returned a falsish va
Camillo Bruni
2015/12/10 20:22:13
updated to kProxyReturnedFalsish
| |
| 4728 factory->false_string(), trap_name)); | 4728 handler, factory->false_string(), trap_name)); |
| 4729 } | 4729 } |
| 4730 | 4730 |
| 4731 // Enforce the invariant. | 4731 // Enforce the invariant. |
| 4732 PropertyDescriptor target_desc; | 4732 PropertyDescriptor target_desc; |
| 4733 Maybe<bool> owned = | 4733 Maybe<bool> owned = |
| 4734 JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc); | 4734 JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc); |
| 4735 MAYBE_RETURN(owned, Nothing<bool>()); | 4735 MAYBE_RETURN(owned, Nothing<bool>()); |
| 4736 if (owned.FromJust()) { | 4736 if (owned.FromJust()) { |
| 4737 bool inconsistent = | 4737 bool inconsistent = |
| 4738 (PropertyDescriptor::IsDataDescriptor(&target_desc) && | 4738 (PropertyDescriptor::IsDataDescriptor(&target_desc) && |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4775 } | 4775 } |
| 4776 | 4776 |
| 4777 Handle<Object> trap_result; | 4777 Handle<Object> trap_result; |
| 4778 Handle<Object> args[] = {target, name}; | 4778 Handle<Object> args[] = {target, name}; |
| 4779 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 4779 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 4780 isolate, trap_result, | 4780 isolate, trap_result, |
| 4781 Execution::Call(isolate, trap, handler, arraysize(args), args), | 4781 Execution::Call(isolate, trap, handler, arraysize(args), args), |
| 4782 Nothing<bool>()); | 4782 Nothing<bool>()); |
| 4783 if (!trap_result->BooleanValue()) { | 4783 if (!trap_result->BooleanValue()) { |
| 4784 RETURN_FAILURE(isolate, should_throw, | 4784 RETURN_FAILURE(isolate, should_throw, |
| 4785 NewTypeError(MessageTemplate::kProxyHandlerReturned, handler, | 4785 NewTypeError(MessageTemplate::kProxyTrapReturnedNonBoolean, |
|
Jakob Kummerow
2015/12/10 15:35:03
same here
| |
| 4786 factory->false_string(), trap_name)); | 4786 handler, factory->false_string(), trap_name)); |
| 4787 } | 4787 } |
| 4788 | 4788 |
| 4789 // Enforce the invariant. | 4789 // Enforce the invariant. |
| 4790 PropertyDescriptor target_desc; | 4790 PropertyDescriptor target_desc; |
| 4791 Maybe<bool> owned = | 4791 Maybe<bool> owned = |
| 4792 JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc); | 4792 JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc); |
| 4793 MAYBE_RETURN(owned, Nothing<bool>()); | 4793 MAYBE_RETURN(owned, Nothing<bool>()); |
| 4794 if (owned.FromJust() && !target_desc.configurable()) { | 4794 if (owned.FromJust() && !target_desc.configurable()) { |
| 4795 isolate->Throw(*factory->NewTypeError( | 4795 isolate->Throw(*factory->NewTypeError( |
| 4796 MessageTemplate::kProxyDeletePropertyViolatesInvariant, name)); | 4796 MessageTemplate::kProxyDeletePropertyViolatesInvariant, name)); |
| (...skipping 2031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6828 ? Handle<Name>::cast(key) | 6828 ? Handle<Name>::cast(key) |
| 6829 : Handle<Name>::cast(isolate->factory()->NumberToString(key)); | 6829 : Handle<Name>::cast(isolate->factory()->NumberToString(key)); |
| 6830 Handle<Object> trap_result_obj; | 6830 Handle<Object> trap_result_obj; |
| 6831 Handle<Object> args[] = {target, property_name, desc_obj}; | 6831 Handle<Object> args[] = {target, property_name, desc_obj}; |
| 6832 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 6832 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 6833 isolate, trap_result_obj, | 6833 isolate, trap_result_obj, |
| 6834 Execution::Call(isolate, trap, handler, arraysize(args), args), | 6834 Execution::Call(isolate, trap, handler, arraysize(args), args), |
| 6835 Nothing<bool>()); | 6835 Nothing<bool>()); |
| 6836 // 10. If booleanTrapResult is false, return false. | 6836 // 10. If booleanTrapResult is false, return false. |
| 6837 if (!trap_result_obj->BooleanValue()) { | 6837 if (!trap_result_obj->BooleanValue()) { |
| 6838 // TODO(jkummerow): Better error message? | |
| 6839 RETURN_FAILURE(isolate, should_throw, | 6838 RETURN_FAILURE(isolate, should_throw, |
| 6840 NewTypeError(MessageTemplate::kProxyHandlerReturned, handler, | 6839 NewTypeError(MessageTemplate::kProxyTrapReturnedNonBoolean, |
| 6841 trap_result_obj, trap_name)); | 6840 handler, trap_result_obj, trap_name)); |
| 6842 } | 6841 } |
|
neis
2015/12/10 15:13:49
(!trap_result_obj->BooleanValue() means that the b
| |
| 6843 // 11. Let targetDesc be ? target.[[GetOwnProperty]](P). | 6842 // 11. Let targetDesc be ? target.[[GetOwnProperty]](P). |
| 6844 PropertyDescriptor target_desc; | 6843 PropertyDescriptor target_desc; |
| 6845 Maybe<bool> target_found = | 6844 Maybe<bool> target_found = |
| 6846 JSReceiver::GetOwnPropertyDescriptor(isolate, target, key, &target_desc); | 6845 JSReceiver::GetOwnPropertyDescriptor(isolate, target, key, &target_desc); |
| 6847 MAYBE_RETURN(target_found, Nothing<bool>()); | 6846 MAYBE_RETURN(target_found, Nothing<bool>()); |
| 6848 // 12. Let extensibleTarget be ? IsExtensible(target). | 6847 // 12. Let extensibleTarget be ? IsExtensible(target). |
| 6849 Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target); | 6848 Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target); |
| 6850 MAYBE_RETURN(maybe_extensible, Nothing<bool>()); | 6849 MAYBE_RETURN(maybe_extensible, Nothing<bool>()); |
| 6851 bool extensible_target = maybe_extensible.FromJust(); | 6850 bool extensible_target = maybe_extensible.FromJust(); |
| 6852 // 13. If Desc has a [[Configurable]] field and if Desc.[[Configurable]] | 6851 // 13. If Desc has a [[Configurable]] field and if Desc.[[Configurable]] |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6998 Handle<Object> trap_result_obj; | 6997 Handle<Object> trap_result_obj; |
| 6999 Handle<Object> args[] = {target, name}; | 6998 Handle<Object> args[] = {target, name}; |
| 7000 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 6999 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 7001 isolate, trap_result_obj, | 7000 isolate, trap_result_obj, |
| 7002 Execution::Call(isolate, trap, handler, arraysize(args), args), | 7001 Execution::Call(isolate, trap, handler, arraysize(args), args), |
| 7003 Nothing<bool>()); | 7002 Nothing<bool>()); |
| 7004 // 9. If Type(trapResultObj) is neither Object nor Undefined, throw a | 7003 // 9. If Type(trapResultObj) is neither Object nor Undefined, throw a |
| 7005 // TypeError exception. | 7004 // TypeError exception. |
| 7006 if (!trap_result_obj->IsJSReceiver() && !trap_result_obj->IsUndefined()) { | 7005 if (!trap_result_obj->IsJSReceiver() && !trap_result_obj->IsUndefined()) { |
| 7007 isolate->Throw(*isolate->factory()->NewTypeError( | 7006 isolate->Throw(*isolate->factory()->NewTypeError( |
| 7008 MessageTemplate::kProxyHandlerReturned, handler, trap_result_obj, | 7007 MessageTemplate::kProxyTrapReturnedNonObject, handler, trap_result_obj, |
| 7009 name)); | 7008 trap_name)); |
| 7010 return Nothing<bool>(); | 7009 return Nothing<bool>(); |
| 7011 } | 7010 } |
| 7012 // 10. Let targetDesc be ? target.[[GetOwnProperty]](P). | 7011 // 10. Let targetDesc be ? target.[[GetOwnProperty]](P). |
| 7013 PropertyDescriptor target_desc; | 7012 PropertyDescriptor target_desc; |
| 7014 Maybe<bool> found = | 7013 Maybe<bool> found = |
| 7015 JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc); | 7014 JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc); |
| 7016 MAYBE_RETURN(found, Nothing<bool>()); | 7015 MAYBE_RETURN(found, Nothing<bool>()); |
| 7017 // 11. If trapResultObj is undefined, then | 7016 // 11. If trapResultObj is undefined, then |
| 7018 if (trap_result_obj->IsUndefined()) { | 7017 if (trap_result_obj->IsUndefined()) { |
| 7019 // 11a. If targetDesc is undefined, return undefined. | 7018 // 11a. If targetDesc is undefined, return undefined. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7055 isolate, extensible_target.FromJust(), desc, &target_desc, name); | 7054 isolate, extensible_target.FromJust(), desc, &target_desc, name); |
| 7056 // 16. If valid is false, throw a TypeError exception. | 7055 // 16. If valid is false, throw a TypeError exception. |
| 7057 MAYBE_RETURN(valid, Nothing<bool>()); | 7056 MAYBE_RETURN(valid, Nothing<bool>()); |
| 7058 DCHECK(valid.FromJust()); | 7057 DCHECK(valid.FromJust()); |
| 7059 // 17. If resultDesc.[[Configurable]] is false, then | 7058 // 17. If resultDesc.[[Configurable]] is false, then |
| 7060 if (!desc->configurable()) { | 7059 if (!desc->configurable()) { |
| 7061 // 17a. If targetDesc is undefined or targetDesc.[[Configurable]] is true: | 7060 // 17a. If targetDesc is undefined or targetDesc.[[Configurable]] is true: |
| 7062 if (target_desc.is_empty() || target_desc.configurable()) { | 7061 if (target_desc.is_empty() || target_desc.configurable()) { |
| 7063 // 17a i. Throw a TypeError exception. | 7062 // 17a i. Throw a TypeError exception. |
| 7064 isolate->Throw(*isolate->factory()->NewTypeError( | 7063 isolate->Throw(*isolate->factory()->NewTypeError( |
| 7065 MessageTemplate::kRedefineDisallowed, name)); | 7064 MessageTemplate::kProxyTrapDescriptorNonConfigurable, trap_name, |
| 7065 name)); | |
| 7066 return Nothing<bool>(); | 7066 return Nothing<bool>(); |
| 7067 } | 7067 } |
| 7068 } | 7068 } |
| 7069 // 18. Return resultDesc. | 7069 // 18. Return resultDesc. |
| 7070 return Just(true); | 7070 return Just(true); |
| 7071 } | 7071 } |
| 7072 | 7072 |
| 7073 | 7073 |
| 7074 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, | 7074 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, |
| 7075 ElementsKind kind, | 7075 ElementsKind kind, |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7338 } | 7338 } |
| 7339 | 7339 |
| 7340 Handle<Object> trap_result; | 7340 Handle<Object> trap_result; |
| 7341 Handle<Object> args[] = {target}; | 7341 Handle<Object> args[] = {target}; |
| 7342 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 7342 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 7343 isolate, trap_result, | 7343 isolate, trap_result, |
| 7344 Execution::Call(isolate, trap, handler, arraysize(args), args), | 7344 Execution::Call(isolate, trap, handler, arraysize(args), args), |
| 7345 Nothing<bool>()); | 7345 Nothing<bool>()); |
| 7346 if (!trap_result->BooleanValue()) { | 7346 if (!trap_result->BooleanValue()) { |
| 7347 RETURN_FAILURE(isolate, should_throw, | 7347 RETURN_FAILURE(isolate, should_throw, |
| 7348 NewTypeError(MessageTemplate::kProxyHandlerReturned, handler, | 7348 NewTypeError(MessageTemplate::kProxyTrapReturnedNonBoolean, |
|
Jakob Kummerow
2015/12/10 15:35:03
same here
| |
| 7349 factory->false_string(), trap_name)); | 7349 handler, factory->false_string(), trap_name)); |
| 7350 } | 7350 } |
| 7351 | 7351 |
| 7352 // Enforce the invariant. | 7352 // Enforce the invariant. |
| 7353 Maybe<bool> target_result = JSReceiver::IsExtensible(target); | 7353 Maybe<bool> target_result = JSReceiver::IsExtensible(target); |
| 7354 MAYBE_RETURN(target_result, Nothing<bool>()); | 7354 MAYBE_RETURN(target_result, Nothing<bool>()); |
| 7355 if (target_result.FromJust()) { | 7355 if (target_result.FromJust()) { |
| 7356 isolate->Throw(*factory->NewTypeError( | 7356 isolate->Throw(*factory->NewTypeError( |
| 7357 MessageTemplate::kProxyPreventExtensionsViolatesInvariant)); | 7357 MessageTemplate::kProxyPreventExtensionsViolatesInvariant)); |
| 7358 return Nothing<bool>(); | 7358 return Nothing<bool>(); |
| 7359 } | 7359 } |
| (...skipping 1217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8577 unchecked_result_keys.Set(trap_result->get(i), kPresent); | 8577 unchecked_result_keys.Set(trap_result->get(i), kPresent); |
| 8578 } | 8578 } |
| 8579 // 17. Repeat, for each key that is an element of targetNonconfigurableKeys: | 8579 // 17. Repeat, for each key that is an element of targetNonconfigurableKeys: |
| 8580 for (int i = 0; i < nonconfigurable_keys_length; ++i) { | 8580 for (int i = 0; i < nonconfigurable_keys_length; ++i) { |
| 8581 Object* key = target_nonconfigurable_keys->get(i); | 8581 Object* key = target_nonconfigurable_keys->get(i); |
| 8582 // 17a. If key is not an element of uncheckedResultKeys, throw a | 8582 // 17a. If key is not an element of uncheckedResultKeys, throw a |
| 8583 // TypeError exception. | 8583 // TypeError exception. |
| 8584 int* found = unchecked_result_keys.Find(key); | 8584 int* found = unchecked_result_keys.Find(key); |
| 8585 if (found == nullptr || *found == kGone) { | 8585 if (found == nullptr || *found == kGone) { |
| 8586 isolate->Throw(*isolate->factory()->NewTypeError( | 8586 isolate->Throw(*isolate->factory()->NewTypeError( |
| 8587 MessageTemplate::kProxyTrapResultMustInclude, handle(key, isolate))); | 8587 MessageTemplate::kProxyTrapOwnKeysResultMustInclude, |
| 8588 handle(key, isolate))); | |
| 8588 return Nothing<bool>(); | 8589 return Nothing<bool>(); |
| 8589 } | 8590 } |
| 8590 // 17b. Remove key from uncheckedResultKeys. | 8591 // 17b. Remove key from uncheckedResultKeys. |
| 8591 *found = kGone; | 8592 *found = kGone; |
| 8592 unchecked_result_keys_size--; | 8593 unchecked_result_keys_size--; |
| 8593 } | 8594 } |
| 8594 // 18. If extensibleTarget is true, return trapResult. | 8595 // 18. If extensibleTarget is true, return trapResult. |
| 8595 if (extensible_target) { | 8596 if (extensible_target) { |
| 8596 return accumulator->AddKeysFromProxy(proxy, trap_result); | 8597 return accumulator->AddKeysFromProxy(proxy, trap_result); |
| 8597 } | 8598 } |
| 8598 // 19. Repeat, for each key that is an element of targetConfigurableKeys: | 8599 // 19. Repeat, for each key that is an element of targetConfigurableKeys: |
| 8599 for (int i = 0; i < target_configurable_keys->length(); ++i) { | 8600 for (int i = 0; i < target_configurable_keys->length(); ++i) { |
| 8600 Object* key = target_configurable_keys->get(i); | 8601 Object* key = target_configurable_keys->get(i); |
| 8601 if (key->IsSmi()) continue; // Zapped entry, was nonconfigurable. | 8602 if (key->IsSmi()) continue; // Zapped entry, was nonconfigurable. |
| 8602 // 19a. If key is not an element of uncheckedResultKeys, throw a | 8603 // 19a. If key is not an element of uncheckedResultKeys, throw a |
| 8603 // TypeError exception. | 8604 // TypeError exception. |
| 8604 int* found = unchecked_result_keys.Find(key); | 8605 int* found = unchecked_result_keys.Find(key); |
| 8605 if (found == nullptr || *found == kGone) { | 8606 if (found == nullptr || *found == kGone) { |
| 8606 isolate->Throw(*isolate->factory()->NewTypeError( | 8607 isolate->Throw(*isolate->factory()->NewTypeError( |
| 8607 MessageTemplate::kProxyTrapResultMustInclude, handle(key, isolate))); | 8608 MessageTemplate::kProxyTrapOwnKeysResultMustInclude, |
| 8609 handle(key, isolate))); | |
| 8608 return Nothing<bool>(); | 8610 return Nothing<bool>(); |
| 8609 } | 8611 } |
| 8610 // 19b. Remove key from uncheckedResultKeys. | 8612 // 19b. Remove key from uncheckedResultKeys. |
| 8611 *found = kGone; | 8613 *found = kGone; |
| 8612 unchecked_result_keys_size--; | 8614 unchecked_result_keys_size--; |
| 8613 } | 8615 } |
| 8614 // 20. If uncheckedResultKeys is not empty, throw a TypeError exception. | 8616 // 20. If uncheckedResultKeys is not empty, throw a TypeError exception. |
| 8615 if (unchecked_result_keys_size != 0) { | 8617 if (unchecked_result_keys_size != 0) { |
| 8616 DCHECK_GT(unchecked_result_keys_size, 0); | 8618 DCHECK_GT(unchecked_result_keys_size, 0); |
| 8617 isolate->Throw(*isolate->factory()->NewTypeError( | 8619 isolate->Throw(*isolate->factory()->NewTypeError( |
| (...skipping 10545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 19163 if (cell->value() != *new_value) { | 19165 if (cell->value() != *new_value) { |
| 19164 cell->set_value(*new_value); | 19166 cell->set_value(*new_value); |
| 19165 Isolate* isolate = cell->GetIsolate(); | 19167 Isolate* isolate = cell->GetIsolate(); |
| 19166 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19168 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 19167 isolate, DependentCode::kPropertyCellChangedGroup); | 19169 isolate, DependentCode::kPropertyCellChangedGroup); |
| 19168 } | 19170 } |
| 19169 } | 19171 } |
| 19170 | 19172 |
| 19171 } // namespace internal | 19173 } // namespace internal |
| 19172 } // namespace v8 | 19174 } // namespace v8 |
| OLD | NEW |