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/key-accumulator.h" | 5 #include "src/key-accumulator.h" |
6 | 6 |
7 #include "src/elements.h" | 7 #include "src/elements.h" |
8 #include "src/factory.h" | 8 #include "src/factory.h" |
| 9 #include "src/isolate-inl.h" |
9 #include "src/objects-inl.h" | 10 #include "src/objects-inl.h" |
| 11 #include "src/property-descriptor.h" |
10 | 12 |
11 | 13 |
12 namespace v8 { | 14 namespace v8 { |
13 namespace internal { | 15 namespace internal { |
14 | 16 |
15 | 17 |
16 KeyAccumulator::~KeyAccumulator() { | 18 KeyAccumulator::~KeyAccumulator() { |
17 for (size_t i = 0; i < elements_.size(); i++) { | 19 for (size_t i = 0; i < elements_.size(); i++) { |
18 delete elements_[i]; | 20 delete elements_[i]; |
19 } | 21 } |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 // elements and properties, which breaks the normal assumption for the | 212 // elements and properties, which breaks the normal assumption for the |
211 // KeyAccumulator. | 213 // KeyAccumulator. |
212 AddKeys(array_like, PROXY_MAGIC); | 214 AddKeys(array_like, PROXY_MAGIC); |
213 // Invert the current length to indicate a present proxy, so we can ignore | 215 // Invert the current length to indicate a present proxy, so we can ignore |
214 // element keys for this level. Otherwise we would not fully respect the order | 216 // element keys for this level. Otherwise we would not fully respect the order |
215 // given by the proxy. | 217 // given by the proxy. |
216 level_string_length_ = -level_string_length_; | 218 level_string_length_ = -level_string_length_; |
217 } | 219 } |
218 | 220 |
219 | 221 |
220 void KeyAccumulator::AddKeysFromProxy(Handle<FixedArray> keys) { | 222 MaybeHandle<FixedArray> FilterProxyKeys(Isolate* isolate, Handle<JSProxy> owner, |
| 223 Handle<FixedArray> keys, |
| 224 KeyFilter filter, |
| 225 Enumerability enum_policy) { |
| 226 if (filter == INCLUDE_SYMBOLS && enum_policy == IGNORE_ENUMERABILITY) { |
| 227 // Nothing to do. |
| 228 return keys; |
| 229 } |
| 230 int store_position = 0; |
| 231 for (int i = 0; i < keys->length(); ++i) { |
| 232 Handle<Name> key(Name::cast(keys->get(i)), isolate); |
| 233 if (filter == SKIP_SYMBOLS && key->IsSymbol()) continue; // Skip this key. |
| 234 if (enum_policy == RESPECT_ENUMERABILITY) { |
| 235 PropertyDescriptor desc; |
| 236 bool found = |
| 237 JSProxy::GetOwnPropertyDescriptor(isolate, owner, key, &desc); |
| 238 if (isolate->has_pending_exception()) return MaybeHandle<FixedArray>(); |
| 239 if (!found || !desc.enumerable()) continue; // Skip this key. |
| 240 } |
| 241 // Keep this key. |
| 242 if (store_position != i) { |
| 243 keys->set(store_position, *key); |
| 244 } |
| 245 store_position++; |
| 246 } |
| 247 if (store_position == 0) return isolate->factory()->empty_fixed_array(); |
| 248 keys->Shrink(store_position); |
| 249 return keys; |
| 250 } |
| 251 |
| 252 |
| 253 // Returns "false" in case of exception, "true" on success. |
| 254 bool KeyAccumulator::AddKeysFromProxy(Handle<JSProxy> proxy, |
| 255 Handle<FixedArray> keys, KeyFilter filter, |
| 256 Enumerability enum_policy) { |
| 257 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 258 isolate_, keys, |
| 259 FilterProxyKeys(isolate_, proxy, keys, filter, enum_policy), false); |
221 // Proxies define a complete list of keys with no distinction of | 260 // Proxies define a complete list of keys with no distinction of |
222 // elements and properties, which breaks the normal assumption for the | 261 // elements and properties, which breaks the normal assumption for the |
223 // KeyAccumulator. | 262 // KeyAccumulator. |
224 AddKeys(keys, PROXY_MAGIC); | 263 AddKeys(keys, PROXY_MAGIC); |
225 // Invert the current length to indicate a present proxy, so we can ignore | 264 // Invert the current length to indicate a present proxy, so we can ignore |
226 // element keys for this level. Otherwise we would not fully respect the order | 265 // element keys for this level. Otherwise we would not fully respect the order |
227 // given by the proxy. | 266 // given by the proxy. |
228 level_string_length_ = -level_string_length_; | 267 level_string_length_ = -level_string_length_; |
| 268 return true; |
229 } | 269 } |
230 | 270 |
231 | 271 |
232 void KeyAccumulator::AddElementKeysFromInterceptor( | 272 void KeyAccumulator::AddElementKeysFromInterceptor( |
233 Handle<JSObject> array_like) { | 273 Handle<JSObject> array_like) { |
234 AddKeys(array_like, CONVERT_TO_ARRAY_INDEX); | 274 AddKeys(array_like, CONVERT_TO_ARRAY_INDEX); |
235 // The interceptor might introduce duplicates for the current level, since | 275 // The interceptor might introduce duplicates for the current level, since |
236 // these keys get added after the objects's normal element keys. | 276 // these keys get added after the objects's normal element keys. |
237 SortCurrentElementsListRemoveDuplicates(); | 277 SortCurrentElementsListRemoveDuplicates(); |
238 } | 278 } |
(...skipping 27 matching lines...) Expand all Loading... |
266 level_lengths_.push_back(level_symbol_length_); | 306 level_lengths_.push_back(level_symbol_length_); |
267 } | 307 } |
268 elements_.push_back(new std::vector<uint32_t>()); | 308 elements_.push_back(new std::vector<uint32_t>()); |
269 level_string_length_ = 0; | 309 level_string_length_ = 0; |
270 level_symbol_length_ = 0; | 310 level_symbol_length_ = 0; |
271 } | 311 } |
272 | 312 |
273 | 313 |
274 } // namespace internal | 314 } // namespace internal |
275 } // namespace v8 | 315 } // namespace v8 |
OLD | NEW |