Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Side by Side Diff: src/keys.cc

Issue 2129193003: [keys] propagate PropertyFilter to proxy targets in KeyAccumulator (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: add tests from the bug Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/keys.h ('k') | src/objects.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/keys.h" 5 #include "src/keys.h"
6 6
7 #include "src/api-arguments.h" 7 #include "src/api-arguments.h"
8 #include "src/elements.h" 8 #include "src/elements.h"
9 #include "src/factory.h" 9 #include "src/factory.h"
10 #include "src/identity-map.h" 10 #include "src/identity-map.h"
(...skipping 20 matching lines...) Expand all
31 } 31 }
32 32
33 } // namespace 33 } // namespace
34 MaybeHandle<FixedArray> KeyAccumulator::GetKeys( 34 MaybeHandle<FixedArray> KeyAccumulator::GetKeys(
35 Handle<JSReceiver> object, KeyCollectionMode mode, PropertyFilter filter, 35 Handle<JSReceiver> object, KeyCollectionMode mode, PropertyFilter filter,
36 GetKeysConversion keys_conversion, bool filter_proxy_keys, bool is_for_in) { 36 GetKeysConversion keys_conversion, bool filter_proxy_keys, bool is_for_in) {
37 Isolate* isolate = object->GetIsolate(); 37 Isolate* isolate = object->GetIsolate();
38 KeyAccumulator accumulator(isolate, mode, filter); 38 KeyAccumulator accumulator(isolate, mode, filter);
39 accumulator.set_filter_proxy_keys(filter_proxy_keys); 39 accumulator.set_filter_proxy_keys(filter_proxy_keys);
40 accumulator.set_is_for_in(is_for_in); 40 accumulator.set_is_for_in(is_for_in);
41 MAYBE_RETURN(accumulator.CollectKeys(object, object), 41 MAYBE_RETURN(accumulator.CollectKeys(object, object, keys_conversion),
42 MaybeHandle<FixedArray>()); 42 MaybeHandle<FixedArray>());
43 return accumulator.GetKeys(keys_conversion); 43 return accumulator.GetKeys(keys_conversion);
44 } 44 }
45 45
46 Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) { 46 Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) {
47 if (keys_.is_null()) { 47 if (keys_.is_null()) {
48 return isolate_->factory()->empty_fixed_array(); 48 return isolate_->factory()->empty_fixed_array();
49 } 49 }
50 if (mode_ == KeyCollectionMode::kOwnOnly && 50 if (mode_ == KeyCollectionMode::kOwnOnly &&
51 keys_->map() == isolate_->heap()->fixed_array_map()) { 51 keys_->map() == isolate_->heap()->fixed_array_map()) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 if (mode_ == KeyCollectionMode::kOwnOnly && !is_for_in_) { 144 if (mode_ == KeyCollectionMode::kOwnOnly && !is_for_in_) {
145 // If we collect only the keys from a JSProxy do not sort or deduplicate it. 145 // If we collect only the keys from a JSProxy do not sort or deduplicate it.
146 keys_ = keys; 146 keys_ = keys;
147 return Just(true); 147 return Just(true);
148 } 148 }
149 AddKeys(keys, is_for_in_ ? CONVERT_TO_ARRAY_INDEX : DO_NOT_CONVERT); 149 AddKeys(keys, is_for_in_ ? CONVERT_TO_ARRAY_INDEX : DO_NOT_CONVERT);
150 return Just(true); 150 return Just(true);
151 } 151 }
152 152
153 Maybe<bool> KeyAccumulator::CollectKeys(Handle<JSReceiver> receiver, 153 Maybe<bool> KeyAccumulator::CollectKeys(Handle<JSReceiver> receiver,
154 Handle<JSReceiver> object) { 154 Handle<JSReceiver> object,
155 GetKeysConversion keys_conversion) {
155 // Proxies have no hidden prototype and we should not trigger the 156 // Proxies have no hidden prototype and we should not trigger the
156 // [[GetPrototypeOf]] trap on the last iteration when using 157 // [[GetPrototypeOf]] trap on the last iteration when using
157 // AdvanceFollowingProxies. 158 // AdvanceFollowingProxies.
158 if (mode_ == KeyCollectionMode::kOwnOnly && object->IsJSProxy()) { 159 if (mode_ == KeyCollectionMode::kOwnOnly && object->IsJSProxy()) {
159 MAYBE_RETURN(CollectOwnJSProxyKeys(receiver, Handle<JSProxy>::cast(object)), 160 MAYBE_RETURN(CollectOwnJSProxyKeys(receiver, Handle<JSProxy>::cast(object),
161 keys_conversion),
160 Nothing<bool>()); 162 Nothing<bool>());
161 return Just(true); 163 return Just(true);
162 } 164 }
163 165
164 PrototypeIterator::WhereToEnd end = mode_ == KeyCollectionMode::kOwnOnly 166 PrototypeIterator::WhereToEnd end = mode_ == KeyCollectionMode::kOwnOnly
165 ? PrototypeIterator::END_AT_NON_HIDDEN 167 ? PrototypeIterator::END_AT_NON_HIDDEN
166 : PrototypeIterator::END_AT_NULL; 168 : PrototypeIterator::END_AT_NULL;
167 for (PrototypeIterator iter(isolate_, object, kStartAtReceiver, end); 169 for (PrototypeIterator iter(isolate_, object, kStartAtReceiver, end);
168 !iter.IsAtEnd();) { 170 !iter.IsAtEnd();) {
169 Handle<JSReceiver> current = 171 Handle<JSReceiver> current =
170 PrototypeIterator::GetCurrent<JSReceiver>(iter); 172 PrototypeIterator::GetCurrent<JSReceiver>(iter);
171 Maybe<bool> result = Just(false); // Dummy initialization. 173 Maybe<bool> result = Just(false); // Dummy initialization.
172 if (current->IsJSProxy()) { 174 if (current->IsJSProxy()) {
173 result = CollectOwnJSProxyKeys(receiver, Handle<JSProxy>::cast(current)); 175 result = CollectOwnJSProxyKeys(receiver, Handle<JSProxy>::cast(current),
176 keys_conversion);
174 } else { 177 } else {
175 DCHECK(current->IsJSObject()); 178 DCHECK(current->IsJSObject());
176 result = CollectOwnKeys(receiver, Handle<JSObject>::cast(current)); 179 result = CollectOwnKeys(receiver, Handle<JSObject>::cast(current));
177 } 180 }
178 MAYBE_RETURN(result, Nothing<bool>()); 181 MAYBE_RETURN(result, Nothing<bool>());
179 if (!result.FromJust()) break; // |false| means "stop iterating". 182 if (!result.FromJust()) break; // |false| means "stop iterating".
180 // Iterate through proxies but ignore access checks for the ALL_CAN_READ 183 // Iterate through proxies but ignore access checks for the ALL_CAN_READ
181 // case on API objects for OWN_ONLY keys handled in CollectOwnKeys. 184 // case on API objects for OWN_ONLY keys handled in CollectOwnKeys.
182 if (!iter.AdvanceFollowingProxiesIgnoringAccessChecks()) { 185 if (!iter.AdvanceFollowingProxiesIgnoringAccessChecks()) {
183 return Nothing<bool>(); 186 return Nothing<bool>();
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 object->global_dictionary()); 699 object->global_dictionary());
697 } else { 700 } else {
698 return GetOwnEnumPropertyDictionaryKeys( 701 return GetOwnEnumPropertyDictionaryKeys(
699 isolate, KeyCollectionMode::kOwnOnly, nullptr, object, 702 isolate, KeyCollectionMode::kOwnOnly, nullptr, object,
700 object->property_dictionary()); 703 object->property_dictionary());
701 } 704 }
702 } 705 }
703 706
704 // ES6 9.5.12 707 // ES6 9.5.12
705 // Returns |true| on success, |nothing| in case of exception. 708 // Returns |true| on success, |nothing| in case of exception.
706 Maybe<bool> KeyAccumulator::CollectOwnJSProxyKeys(Handle<JSReceiver> receiver, 709 Maybe<bool> KeyAccumulator::CollectOwnJSProxyKeys(
707 Handle<JSProxy> proxy) { 710 Handle<JSReceiver> receiver, Handle<JSProxy> proxy,
711 GetKeysConversion keys_conversion) {
708 STACK_CHECK(isolate_, Nothing<bool>()); 712 STACK_CHECK(isolate_, Nothing<bool>());
709 // 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. 713 // 1. Let handler be the value of the [[ProxyHandler]] internal slot of O.
710 Handle<Object> handler(proxy->handler(), isolate_); 714 Handle<Object> handler(proxy->handler(), isolate_);
711 // 2. If handler is null, throw a TypeError exception. 715 // 2. If handler is null, throw a TypeError exception.
712 // 3. Assert: Type(handler) is Object. 716 // 3. Assert: Type(handler) is Object.
713 if (proxy->IsRevoked()) { 717 if (proxy->IsRevoked()) {
714 isolate_->Throw(*isolate_->factory()->NewTypeError( 718 isolate_->Throw(*isolate_->factory()->NewTypeError(
715 MessageTemplate::kProxyRevoked, isolate_->factory()->ownKeys_string())); 719 MessageTemplate::kProxyRevoked, isolate_->factory()->ownKeys_string()));
716 return Nothing<bool>(); 720 return Nothing<bool>();
717 } 721 }
718 // 4. Let target be the value of the [[ProxyTarget]] internal slot of O. 722 // 4. Let target be the value of the [[ProxyTarget]] internal slot of O.
719 Handle<JSReceiver> target(proxy->target(), isolate_); 723 Handle<JSReceiver> target(proxy->target(), isolate_);
720 // 5. Let trap be ? GetMethod(handler, "ownKeys"). 724 // 5. Let trap be ? GetMethod(handler, "ownKeys").
721 Handle<Object> trap; 725 Handle<Object> trap;
722 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 726 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
723 isolate_, trap, Object::GetMethod(Handle<JSReceiver>::cast(handler), 727 isolate_, trap, Object::GetMethod(Handle<JSReceiver>::cast(handler),
724 isolate_->factory()->ownKeys_string()), 728 isolate_->factory()->ownKeys_string()),
725 Nothing<bool>()); 729 Nothing<bool>());
726 // 6. If trap is undefined, then 730 // 6. If trap is undefined, then
727 if (trap->IsUndefined(isolate_)) { 731 if (trap->IsUndefined(isolate_)) {
728 // 6a. Return target.[[OwnPropertyKeys]](). 732 // 6a. Return target.[[OwnPropertyKeys]]().
729 return CollectOwnJSProxyTargetKeys(proxy, target); 733 return CollectOwnJSProxyTargetKeys(proxy, target, keys_conversion);
730 } 734 }
731 // 7. Let trapResultArray be Call(trap, handler, «target»). 735 // 7. Let trapResultArray be Call(trap, handler, «target»).
732 Handle<Object> trap_result_array; 736 Handle<Object> trap_result_array;
733 Handle<Object> args[] = {target}; 737 Handle<Object> args[] = {target};
734 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 738 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
735 isolate_, trap_result_array, 739 isolate_, trap_result_array,
736 Execution::Call(isolate_, trap, handler, arraysize(args), args), 740 Execution::Call(isolate_, trap, handler, arraysize(args), args),
737 Nothing<bool>()); 741 Nothing<bool>());
738 // 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, 742 // 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray,
739 // «String, Symbol»). 743 // «String, Symbol»).
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 DCHECK_GT(unchecked_result_keys_size, 0); 846 DCHECK_GT(unchecked_result_keys_size, 0);
843 isolate_->Throw(*isolate_->factory()->NewTypeError( 847 isolate_->Throw(*isolate_->factory()->NewTypeError(
844 MessageTemplate::kProxyOwnKeysNonExtensible)); 848 MessageTemplate::kProxyOwnKeysNonExtensible));
845 return Nothing<bool>(); 849 return Nothing<bool>();
846 } 850 }
847 // 21. Return trapResult. 851 // 21. Return trapResult.
848 return AddKeysFromJSProxy(proxy, trap_result); 852 return AddKeysFromJSProxy(proxy, trap_result);
849 } 853 }
850 854
851 Maybe<bool> KeyAccumulator::CollectOwnJSProxyTargetKeys( 855 Maybe<bool> KeyAccumulator::CollectOwnJSProxyTargetKeys(
852 Handle<JSProxy> proxy, Handle<JSReceiver> target) { 856 Handle<JSProxy> proxy, Handle<JSReceiver> target,
857 GetKeysConversion keys_conversion) {
853 // TODO(cbruni): avoid creating another KeyAccumulator 858 // TODO(cbruni): avoid creating another KeyAccumulator
854 Handle<FixedArray> keys; 859 Handle<FixedArray> keys;
855 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 860 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
856 isolate_, keys, JSReceiver::OwnPropertyKeys(target), Nothing<bool>()); 861 isolate_, keys,
862 KeyAccumulator::GetKeys(target, KeyCollectionMode::kOwnOnly, filter_,
Dan Ehrenberg 2016/07/08 22:02:07 It looks like the relevant change here is passing
863 keys_conversion, filter_proxy_keys_, is_for_in_),
864 Nothing<bool>());
857 bool prev_filter_proxy_keys_ = filter_proxy_keys_; 865 bool prev_filter_proxy_keys_ = filter_proxy_keys_;
858 filter_proxy_keys_ = false; 866 filter_proxy_keys_ = false;
859 Maybe<bool> result = AddKeysFromJSProxy(proxy, keys); 867 Maybe<bool> result = AddKeysFromJSProxy(proxy, keys);
860 filter_proxy_keys_ = prev_filter_proxy_keys_; 868 filter_proxy_keys_ = prev_filter_proxy_keys_;
861 return result; 869 return result;
862 } 870 }
863 871
864 } // namespace internal 872 } // namespace internal
865 } // namespace v8 873 } // namespace v8
OLDNEW
« no previous file with comments | « src/keys.h ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698