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

Side by Side Diff: src/runtime/runtime-forin.cc

Issue 1748923003: [proxies] use [[GetPrototypeOf]] trap in for-in (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: do not create a HandleScope when passing LookuptIterator* Created 4 years, 9 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
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/runtime/runtime-utils.h" 5 #include "src/runtime/runtime-utils.h"
6 6
7 #include "src/arguments.h" 7 #include "src/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/isolate-inl.h" 10 #include "src/isolate-inl.h"
11 #include "src/keys.h" 11 #include "src/keys.h"
12 #include "src/objects-inl.h" 12 #include "src/objects-inl.h"
13 13
14 namespace v8 { 14 namespace v8 {
15 namespace internal { 15 namespace internal {
16 16
17 namespace { 17 namespace {
18 18
19 // Returns either a FixedArray or, if the given {receiver} has an enum cache 19 // Returns either a FixedArray or, if the given {receiver} has an enum cache
20 // that contains all enumerable properties of the {receiver} and its prototypes 20 // that contains all enumerable properties of the {receiver} and its prototypes
21 // have none, the map of the {receiver}. This is used to speed up the check for 21 // have none, the map of the {receiver}. This is used to speed up the check for
22 // deletions during a for-in. 22 // deletions during a for-in.
23 MaybeHandle<HeapObject> Enumerate(Handle<JSReceiver> receiver) { 23 MaybeHandle<HeapObject> Enumerate(Handle<JSReceiver> receiver) {
24 Isolate* const isolate = receiver->GetIsolate(); 24 Isolate* const isolate = receiver->GetIsolate();
25 FastKeyAccumulator accumulator(isolate, receiver, INCLUDE_PROTOS, 25 FastKeyAccumulator accumulator(isolate, receiver, INCLUDE_PROTOS,
26 ENUMERABLE_STRINGS); 26 ENUMERABLE_STRINGS);
27 accumulator.set_filter_proxy_keys(false);
27 // Test if we have an enum cache for {receiver}. 28 // Test if we have an enum cache for {receiver}.
28 if (!accumulator.is_receiver_simple_enum()) { 29 if (!accumulator.is_receiver_simple_enum()) {
29 Handle<FixedArray> keys; 30 Handle<FixedArray> keys;
30 ASSIGN_RETURN_ON_EXCEPTION(isolate, keys, accumulator.GetKeys(KEEP_NUMBERS), 31 ASSIGN_RETURN_ON_EXCEPTION(isolate, keys, accumulator.GetKeys(KEEP_NUMBERS),
31 HeapObject); 32 HeapObject);
32 // Test again, since cache may have been built by GetKeys() calls above. 33 // Test again, since cache may have been built by GetKeys() calls above.
33 if (!accumulator.is_receiver_simple_enum()) return keys; 34 if (!accumulator.is_receiver_simple_enum()) return keys;
34 } 35 }
35 return handle(receiver->map(), isolate); 36 return handle(receiver->map(), isolate);
36 } 37 }
37 38
39 // This is a slight modifcation of JSReceiver::HasProperty, dealing with
Jakob Kummerow 2016/03/18 14:12:00 nit: missng 'i' ;-)
Camillo Bruni 2016/03/18 17:46:34 shorter is better, no ;)
40 // the oddities of JSProxy in for-in filter.
41 MaybeHandle<Object> HasEnumerableProperty(Isolate* isolate,
42 Handle<JSReceiver> receiver,
43 Handle<Object> key) {
44 bool success = false;
45 Maybe<PropertyAttributes> result = Just(ABSENT);
46 LookupIterator it =
47 LookupIterator::PropertyOrElement(isolate, receiver, key, &success);
48 if (!success) return isolate->factory()->undefined_value();
49 for (; it.IsFound(); it.Next()) {
50 switch (it.state()) {
51 case LookupIterator::NOT_FOUND:
52 case LookupIterator::TRANSITION:
53 UNREACHABLE();
54 case LookupIterator::JSPROXY: {
55 // For proxies we have to invoke the [[GetOwnProperty]] trap.
56 result = JSProxy::GetPropertyAttributes(&it);
57 if (result.IsNothing()) return MaybeHandle<Object>();
58 if (result.FromJust() == ABSENT) {
59 // Continue lookup on the proxy's prototype.
60 Handle<JSProxy> proxy = it.GetHolder<JSProxy>();
61 Handle<Object> prototype;
62 ASSIGN_RETURN_ON_EXCEPTION(isolate, prototype,
63 JSProxy::GetPrototype(proxy), Object);
64 if (prototype->IsNull()) break;
65 // We already have a stack-check in JSProxy::GetPrototype.
66 return HasEnumerableProperty(
67 isolate, Handle<JSReceiver>::cast(prototype), key);
68 } else if (result.FromJust() & DONT_ENUM) {
69 return isolate->factory()->undefined_value();
70 } else {
71 return it.GetName();
72 }
73 }
74 case LookupIterator::INTERCEPTOR: {
75 result = JSObject::GetPropertyAttributesWithInterceptor(&it);
76 if (result.IsNothing()) return MaybeHandle<Object>();
77 if (result.FromJust() != ABSENT) return it.GetName();
78 continue;
79 }
80 case LookupIterator::ACCESS_CHECK: {
81 if (it.HasAccess()) continue;
82 result = JSObject::GetPropertyAttributesWithFailedAccessCheck(&it);
83 if (result.IsNothing()) return MaybeHandle<Object>();
84 if (result.FromJust() != ABSENT) return it.GetName();
85 return isolate->factory()->undefined_value();
86 }
87 case LookupIterator::INTEGER_INDEXED_EXOTIC:
88 // TypedArray out-of-bounds access.
89 return isolate->factory()->undefined_value();
90 case LookupIterator::ACCESSOR:
91 case LookupIterator::DATA:
92 return it.GetName();
93 }
94 }
95 return isolate->factory()->undefined_value();
96 }
38 97
39 MaybeHandle<Object> Filter(Handle<JSReceiver> receiver, Handle<Object> key) { 98 MaybeHandle<Object> Filter(Handle<JSReceiver> receiver, Handle<Object> key) {
40 Isolate* const isolate = receiver->GetIsolate(); 99 Isolate* const isolate = receiver->GetIsolate();
41 Handle<Name> name; 100 return HasEnumerableProperty(isolate, receiver, key);
42 ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key),
43 Object);
44 // Directly check for elements if the key is a smi and avoid a conversion
45 // roundtrip (Number -> Name -> Number).
46 if (key->IsNumber() && receiver->map()->OnlyHasSimpleProperties()) {
47 Handle<JSObject> object = Handle<JSObject>::cast(receiver);
48 ElementsAccessor* accessor = object->GetElementsAccessor();
49 DCHECK_LT(key->Number(), kMaxUInt32);
50 if (accessor->HasElement(object, key->Number(), ONLY_ENUMERABLE)) {
51 return name;
52 }
53 }
54 Maybe<bool> result = JSReceiver::HasProperty(receiver, name);
55 MAYBE_RETURN_NULL(result);
56 if (result.FromJust()) return name;
57 return isolate->factory()->undefined_value();
58 } 101 }
59 102
60 } // namespace 103 } // namespace
61 104
62 105
63 RUNTIME_FUNCTION(Runtime_ForInEnumerate) { 106 RUNTIME_FUNCTION(Runtime_ForInEnumerate) {
64 HandleScope scope(isolate); 107 HandleScope scope(isolate);
65 DCHECK_EQ(1, args.length()); 108 DCHECK_EQ(1, args.length());
66 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); 109 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
67 Handle<HeapObject> result; 110 Handle<HeapObject> result;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 SealHandleScope scope(isolate); 187 SealHandleScope scope(isolate);
145 DCHECK_EQ(1, args.length()); 188 DCHECK_EQ(1, args.length());
146 CONVERT_SMI_ARG_CHECKED(index, 0); 189 CONVERT_SMI_ARG_CHECKED(index, 0);
147 DCHECK_LE(0, index); 190 DCHECK_LE(0, index);
148 DCHECK_LT(index, Smi::kMaxValue); 191 DCHECK_LT(index, Smi::kMaxValue);
149 return Smi::FromInt(index + 1); 192 return Smi::FromInt(index + 1);
150 } 193 }
151 194
152 } // namespace internal 195 } // namespace internal
153 } // namespace v8 196 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698