OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/elements.h" | 5 #include "src/elements.h" |
6 | 6 |
7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
9 #include "src/factory.h" | 9 #include "src/factory.h" |
10 #include "src/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
482 Handle<Object> element_k; | 482 Handle<Object> element_k; |
483 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, element_k, | 483 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, element_k, |
484 Object::GetProperty(&it), Nothing<bool>()); | 484 Object::GetProperty(&it), Nothing<bool>()); |
485 | 485 |
486 if (value->SameValueZero(*element_k)) return Just(true); | 486 if (value->SameValueZero(*element_k)) return Just(true); |
487 } | 487 } |
488 | 488 |
489 return Just(false); | 489 return Just(false); |
490 } | 490 } |
491 | 491 |
492 static Maybe<int32_t> IndexOfValueSlowPath(Isolate* isolate, | |
493 Handle<JSObject> receiver, | |
494 Handle<Object> value, | |
495 uint32_t start_from, | |
496 uint32_t length) { | |
497 for (uint32_t k = start_from; k < length; ++k) { | |
498 LookupIterator it(isolate, receiver, k); | |
499 if (!it.IsFound()) { | |
500 continue; | |
501 } | |
502 Handle<Object> element_k; | |
503 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
504 isolate, element_k, Object::GetProperty(&it), Nothing<int32_t>()); | |
505 | |
506 if (value->StrictEquals(*element_k)) return Just(static_cast<int32_t>(k)); | |
507 } | |
508 | |
509 return Just(-1); | |
510 } | |
511 | |
492 // Base class for element handler implementations. Contains the | 512 // Base class for element handler implementations. Contains the |
493 // the common logic for objects with different ElementsKinds. | 513 // the common logic for objects with different ElementsKinds. |
494 // Subclasses must specialize method for which the element | 514 // Subclasses must specialize method for which the element |
495 // implementation differs from the base class implementation. | 515 // implementation differs from the base class implementation. |
496 // | 516 // |
497 // This class is intended to be used in the following way: | 517 // This class is intended to be used in the following way: |
498 // | 518 // |
499 // class SomeElementsAccessor : | 519 // class SomeElementsAccessor : |
500 // public ElementsAccessorBase<SomeElementsAccessor, | 520 // public ElementsAccessorBase<SomeElementsAccessor, |
501 // BackingStoreClass> { | 521 // BackingStoreClass> { |
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1116 return IncludesValueSlowPath(isolate, receiver, value, start_from, length); | 1136 return IncludesValueSlowPath(isolate, receiver, value, start_from, length); |
1117 } | 1137 } |
1118 | 1138 |
1119 Maybe<bool> IncludesValue(Isolate* isolate, Handle<JSObject> receiver, | 1139 Maybe<bool> IncludesValue(Isolate* isolate, Handle<JSObject> receiver, |
1120 Handle<Object> value, uint32_t start_from, | 1140 Handle<Object> value, uint32_t start_from, |
1121 uint32_t length) final { | 1141 uint32_t length) final { |
1122 return Subclass::IncludesValueImpl(isolate, receiver, value, start_from, | 1142 return Subclass::IncludesValueImpl(isolate, receiver, value, start_from, |
1123 length); | 1143 length); |
1124 } | 1144 } |
1125 | 1145 |
1146 static Maybe<int32_t> IndexOfValueImpl(Isolate* isolate, | |
1147 Handle<JSObject> receiver, | |
1148 Handle<Object> value, | |
1149 uint32_t start_from, uint32_t length) { | |
1150 return IndexOfValueSlowPath(isolate, receiver, value, start_from, length); | |
1151 } | |
1152 | |
1153 Maybe<int32_t> IndexOfValue(Isolate* isolate, Handle<JSObject> receiver, | |
1154 Handle<Object> value, uint32_t start_from, | |
1155 uint32_t length) final { | |
1156 return Subclass::IndexOfValueImpl(isolate, receiver, value, start_from, | |
1157 length); | |
1158 } | |
1159 | |
1126 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, | 1160 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, |
1127 uint32_t entry) { | 1161 uint32_t entry) { |
1128 return entry; | 1162 return entry; |
1129 } | 1163 } |
1130 | 1164 |
1131 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 1165 static uint32_t GetEntryForIndexImpl(JSObject* holder, |
1132 FixedArrayBase* backing_store, | 1166 FixedArrayBase* backing_store, |
1133 uint32_t index, PropertyFilter filter) { | 1167 uint32_t index, PropertyFilter filter) { |
1134 if (IsHoleyElementsKind(kind())) { | 1168 if (IsHoleyElementsKind(kind())) { |
1135 return index < Subclass::GetCapacityImpl(holder, backing_store) && | 1169 return index < Subclass::GetCapacityImpl(holder, backing_store) && |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1564 length); | 1598 length); |
1565 } | 1599 } |
1566 dictionary = handle( | 1600 dictionary = handle( |
1567 SeededNumberDictionary::cast(receiver->elements()), isolate); | 1601 SeededNumberDictionary::cast(receiver->elements()), isolate); |
1568 break; | 1602 break; |
1569 } | 1603 } |
1570 } | 1604 } |
1571 } | 1605 } |
1572 return Just(false); | 1606 return Just(false); |
1573 } | 1607 } |
1608 | |
1609 static Maybe<int32_t> IndexOfValueImpl(Isolate* isolate, | |
1610 Handle<JSObject> receiver, | |
1611 Handle<Object> value, | |
1612 uint32_t start_from, uint32_t length) { | |
1613 DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver)); | |
1614 | |
1615 Handle<SeededNumberDictionary> dictionary( | |
1616 SeededNumberDictionary::cast(receiver->elements()), isolate); | |
1617 // Iterate through entire range, as accessing elements out of order is | |
1618 // observable | |
Jakob Kummerow
2016/08/17 15:42:58
nit: trailing full stop.
mattloring
2016/08/17 23:27:21
Done.
| |
1619 for (uint32_t k = start_from; k < length; ++k) { | |
1620 int entry = dictionary->FindEntry(k); | |
1621 if (entry == SeededNumberDictionary::kNotFound) { | |
1622 continue; | |
1623 } | |
1624 | |
1625 PropertyDetails details = GetDetailsImpl(*dictionary, entry); | |
1626 switch (details.kind()) { | |
1627 case kData: { | |
1628 Object* element_k = dictionary->ValueAt(entry); | |
1629 if (value->StrictEquals(element_k)) | |
1630 return Just(static_cast<int32_t>(k)); | |
Jakob Kummerow
2016/08/17 15:42:58
Who guarantees that k is in int32_t range?
Also,
mattloring
2016/08/18 19:03:10
Done.
| |
1631 break; | |
1632 } | |
1633 case kAccessor: { | |
1634 LookupIterator it(isolate, receiver, k, | |
1635 LookupIterator::OWN_SKIP_INTERCEPTOR); | |
1636 DCHECK(it.IsFound()); | |
1637 DCHECK_EQ(it.state(), LookupIterator::ACCESSOR); | |
1638 Handle<Object> element_k; | |
1639 | |
1640 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
1641 isolate, element_k, JSObject::GetPropertyWithAccessor(&it), | |
1642 Nothing<int32_t>()); | |
1643 | |
1644 if (value->StrictEquals(*element_k)) | |
1645 return Just(static_cast<int32_t>(k)); | |
Jakob Kummerow
2016/08/17 15:42:58
nit: braces
mattloring
2016/08/17 23:27:20
Done.
| |
1646 | |
1647 // Bailout to slow path if elements on prototype changed | |
Jakob Kummerow
2016/08/17 15:42:58
nit: trailing full stop.
mattloring
2016/08/17 23:27:20
Done.
| |
1648 if (!JSObject::PrototypeHasNoElements(isolate, *receiver)) { | |
1649 return IndexOfValueSlowPath(isolate, receiver, value, k + 1, | |
1650 length); | |
1651 } | |
1652 | |
1653 // Continue if elements unchanged | |
Jakob Kummerow
2016/08/17 15:42:58
nit: trailing full stop.
mattloring
2016/08/17 23:27:20
Done.
| |
1654 if (*dictionary == receiver->elements()) continue; | |
1655 | |
1656 // Otherwise, bailout or update elements | |
Jakob Kummerow
2016/08/17 15:42:59
nit: trailing full stop.
mattloring
2016/08/17 23:27:20
Done.
| |
1657 if (receiver->GetElementsKind() != DICTIONARY_ELEMENTS) { | |
1658 // Otherwise, switch to slow path. | |
1659 return IndexOfValueSlowPath(isolate, receiver, value, k + 1, | |
1660 length); | |
1661 } | |
1662 dictionary = handle( | |
1663 SeededNumberDictionary::cast(receiver->elements()), isolate); | |
1664 break; | |
1665 } | |
1666 } | |
1667 } | |
1668 return Just(-1); | |
1669 } | |
1574 }; | 1670 }; |
1575 | 1671 |
1576 | 1672 |
1577 // Super class for all fast element arrays. | 1673 // Super class for all fast element arrays. |
1578 template <typename Subclass, typename KindTraits> | 1674 template <typename Subclass, typename KindTraits> |
1579 class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { | 1675 class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { |
1580 public: | 1676 public: |
1581 explicit FastElementsAccessor(const char* name) | 1677 explicit FastElementsAccessor(const char* name) |
1582 : ElementsAccessorBase<Subclass, KindTraits>(name) {} | 1678 : ElementsAccessorBase<Subclass, KindTraits>(name) {} |
1583 | 1679 |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2074 | 2170 |
2075 for (uint32_t k = start_from; k < length; ++k) { | 2171 for (uint32_t k = start_from; k < length; ++k) { |
2076 if (elements->get(k)->IsNaN()) return Just(true); | 2172 if (elements->get(k)->IsNaN()) return Just(true); |
2077 } | 2173 } |
2078 return Just(false); | 2174 return Just(false); |
2079 } | 2175 } |
2080 } | 2176 } |
2081 } | 2177 } |
2082 } | 2178 } |
2083 | 2179 |
2180 static Maybe<int32_t> IndexOfValueImpl(Isolate* isolate, | |
2181 Handle<JSObject> receiver, | |
2182 Handle<Object> search_value, | |
2183 uint32_t start_from, uint32_t length) { | |
2184 DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver)); | |
2185 DisallowHeapAllocation no_gc; | |
2186 FixedArrayBase* elements_base = receiver->elements(); | |
2187 Object* the_hole = isolate->heap()->the_hole_value(); | |
2188 Object* undefined = isolate->heap()->undefined_value(); | |
2189 Object* value = *search_value; | |
2190 | |
2191 if (start_from >= length) return Just(-1); | |
2192 | |
2193 length = std::min(static_cast<uint32_t>(elements_base->length()), length); | |
2194 | |
2195 if (!value->IsNumber()) { | |
2196 if (value == undefined) { | |
2197 // Only FAST_ELEMENTS, FAST_HOLEY_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, and | |
2198 // FAST_HOLEY_DOUBLE_ELEMENTS can have `undefined` as a value. | |
Jakob Kummerow
2016/08/17 15:42:58
The comment below contradicts this, saying that FA
mattloring
2016/08/18 19:03:10
Done.
| |
2199 if (!IsFastObjectElementsKind(Subclass::kind()) && | |
2200 !IsFastHoleyElementsKind(Subclass::kind())) { | |
Jakob Kummerow
2016/08/17 15:42:59
This line can go.
mattloring
2016/08/18 19:03:10
Shouldn't the check for FAST_ELEMENTS/FAST_HOLEY_E
| |
2201 return Just(-1); | |
2202 } | |
2203 | |
2204 // Search for `undefined` in FAST_ELEMENTS, | |
2205 // FAST_HOLEY_ELEMENTS or FAST_HOLEY_SMI_ELEMENTS | |
2206 if (IsFastSmiOrObjectElementsKind(Subclass::kind())) { | |
Jakob Kummerow
2016/08/17 15:42:58
This check (including its comment) can go.
mattloring
2016/08/18 19:03:10
Done.
| |
2207 auto elements = FixedArray::cast(receiver->elements()); | |
Jakob Kummerow
2016/08/17 15:42:58
nit: s/auto/FixedArray*/
mattloring
2016/08/17 23:27:21
Done.
| |
2208 | |
2209 for (uint32_t k = start_from; k < length; ++k) { | |
2210 Object* element_k = elements->get(k); | |
Jakob Kummerow
2016/08/17 15:42:59
I'd inline this.
mattloring
2016/08/17 23:27:21
Done.
| |
2211 if (IsFastObjectElementsKind(Subclass::kind()) && | |
Jakob Kummerow
2016/08/17 15:42:58
No elements kind check necessary here
mattloring
2016/08/18 19:03:10
Done.
| |
2212 element_k == undefined) { | |
2213 return Just(static_cast<int32_t>(k)); | |
2214 } | |
2215 } | |
2216 return Just(-1); | |
2217 } else { | |
Jakob Kummerow
2016/08/17 15:42:58
The entire else-block is unnecessary
mattloring
2016/08/18 19:03:10
Done.
| |
2218 // FAST_HOLEY_DOUBLE_ELEMENTS cannot contain `undefined` | |
2219 DCHECK_EQ(Subclass::kind(), FAST_HOLEY_DOUBLE_ELEMENTS); | |
2220 return Just(-1); | |
2221 } | |
2222 } else if (!IsFastObjectElementsKind(Subclass::kind())) { | |
Jakob Kummerow
2016/08/17 15:42:58
This entire block is subsumed by the above.
mattloring
2016/08/18 19:03:10
Done.
| |
2223 // Search for non-number, non-Undefined value, with either | |
2224 // FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS or | |
2225 // FAST_HOLEY_DOUBLE_ELEMENTS. Guaranteed to return false, since these | |
2226 // elements kinds can only contain Number values or undefined. | |
2227 return Just(-1); | |
2228 } else { | |
2229 // Search for non-number, non-Undefined value with either | |
2230 // FAST_ELEMENTS or FAST_HOLEY_ELEMENTS. | |
2231 DCHECK(IsFastObjectElementsKind(Subclass::kind())); | |
2232 auto elements = FixedArray::cast(receiver->elements()); | |
Jakob Kummerow
2016/08/17 15:42:58
nit: s/auto/FixedArray*/
mattloring
2016/08/17 23:27:21
Done.
| |
2233 | |
2234 for (uint32_t k = start_from; k < length; ++k) { | |
2235 Object* element_k = elements->get(k); | |
2236 if (IsFastHoleyElementsKind(Subclass::kind()) && | |
2237 element_k == the_hole) { | |
2238 continue; | |
2239 } | |
2240 | |
2241 if (value->StrictEquals(element_k)) { | |
2242 return Just(static_cast<int32_t>(k)); | |
2243 } | |
2244 } | |
2245 return Just(-1); | |
2246 } | |
2247 } else { | |
2248 if (!value->IsNaN()) { | |
Jakob Kummerow
2016/08/17 15:42:58
nit: reduce indentation by reversing order:
// Na
mattloring
2016/08/18 19:03:10
Done.
| |
2249 double search_value = value->Number(); | |
2250 if (IsFastDoubleElementsKind(Subclass::kind())) { | |
2251 // Search for non-NaN Number in FAST_DOUBLE_ELEMENTS or | |
Jakob Kummerow
2016/08/17 15:42:58
I don't understand what value this comment adds?
mattloring
2016/08/18 19:03:10
Done.
| |
2252 // FAST_HOLEY_DOUBLE_ELEMENTS --- Skip TheHole, and trust UCOMISD or | |
2253 // similar operation for result. | |
2254 auto elements = FixedDoubleArray::cast(receiver->elements()); | |
Jakob Kummerow
2016/08/17 15:42:58
nit: s/auto/FixedDoubleArray*/
mattloring
2016/08/17 23:27:20
Done.
| |
2255 | |
2256 for (uint32_t k = start_from; k < length; ++k) { | |
2257 if (IsFastHoleyElementsKind(Subclass::kind()) && | |
2258 elements->is_the_hole(k)) { | |
2259 continue; | |
2260 } | |
2261 if (elements->get_scalar(k) == search_value) { | |
2262 return Just(static_cast<int32_t>(k)); | |
2263 } | |
2264 } | |
2265 return Just(-1); | |
2266 } else { | |
2267 // Search for non-NaN Number in FAST_ELEMENTS, FAST_HOLEY_ELEMENTS, | |
2268 // FAST_SMI_ELEMENTS or FAST_HOLEY_SMI_ELEMENTS --- Skip non-Numbers, | |
2269 // and trust UCOMISD or similar operation for result | |
Jakob Kummerow
2016/08/17 15:42:59
nit: if you think this comment is useful enough to
mattloring
2016/08/18 19:03:10
Done.
| |
2270 auto elements = FixedArray::cast(receiver->elements()); | |
Jakob Kummerow
2016/08/17 15:42:59
nit: s/auto/FixedArray*/
mattloring
2016/08/17 23:27:21
Done.
| |
2271 | |
2272 for (uint32_t k = start_from; k < length; ++k) { | |
2273 Object* element_k = elements->get(k); | |
2274 if (element_k->IsNumber() && element_k->Number() == search_value) { | |
2275 return Just(static_cast<int32_t>(k)); | |
2276 } | |
2277 } | |
2278 return Just(-1); | |
2279 } | |
2280 } else { | |
2281 // NaN can never be found by strict equality. | |
2282 return Just(-1); | |
2283 } | |
2284 } | |
2285 } | |
2286 | |
2084 private: | 2287 private: |
2085 // SpliceShrinkStep might modify the backing_store. | 2288 // SpliceShrinkStep might modify the backing_store. |
2086 static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver, | 2289 static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver, |
2087 Handle<FixedArrayBase> backing_store, | 2290 Handle<FixedArrayBase> backing_store, |
2088 uint32_t start, uint32_t delete_count, | 2291 uint32_t start, uint32_t delete_count, |
2089 uint32_t add_count, uint32_t len, | 2292 uint32_t add_count, uint32_t len, |
2090 uint32_t new_length) { | 2293 uint32_t new_length) { |
2091 const int move_left_count = len - delete_count - start; | 2294 const int move_left_count = len - delete_count - start; |
2092 const int move_left_dst_index = start + add_count; | 2295 const int move_left_dst_index = start + add_count; |
2093 Subclass::MoveElements(isolate, receiver, backing_store, | 2296 Subclass::MoveElements(isolate, receiver, backing_store, |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2584 } | 2787 } |
2585 return Just(false); | 2788 return Just(false); |
2586 } else { | 2789 } else { |
2587 for (uint32_t k = start_from; k < length; ++k) { | 2790 for (uint32_t k = start_from; k < length; ++k) { |
2588 double element_k = elements->get_scalar(k); | 2791 double element_k = elements->get_scalar(k); |
2589 if (std::isnan(element_k)) return Just(true); | 2792 if (std::isnan(element_k)) return Just(true); |
2590 } | 2793 } |
2591 return Just(false); | 2794 return Just(false); |
2592 } | 2795 } |
2593 } | 2796 } |
2797 | |
2798 static Maybe<int32_t> IndexOfValueImpl(Isolate* isolate, | |
2799 Handle<JSObject> receiver, | |
2800 Handle<Object> value, | |
2801 uint32_t start_from, uint32_t length) { | |
2802 DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver)); | |
2803 DisallowHeapAllocation no_gc; | |
2804 | |
2805 BackingStore* elements = BackingStore::cast(receiver->elements()); | |
2806 if (!value->IsNumber()) return Just(-1); | |
2807 | |
2808 double search_value = value->Number(); | |
2809 | |
2810 if (!std::isfinite(search_value)) { | |
2811 // Integral types cannot represent +Inf or NaN | |
Jakob Kummerow
2016/08/17 15:42:58
nit: trailing full stop.
mattloring
2016/08/17 23:27:21
Done.
| |
2812 if (AccessorClass::kind() < FLOAT32_ELEMENTS || | |
2813 AccessorClass::kind() > FLOAT64_ELEMENTS) { | |
2814 return Just(-1); | |
2815 } | |
2816 } else if (search_value < std::numeric_limits<ctype>::lowest() || | |
2817 search_value > std::numeric_limits<ctype>::max()) { | |
2818 // Return false if value can't be represented in this space | |
Jakob Kummerow
2016/08/17 15:42:58
nit: trailing full stop. s/space/ElementsKind/?
mattloring
2016/08/17 23:27:20
Done.
| |
2819 return Just(-1); | |
2820 } | |
2821 | |
2822 // Prototype has no elements, and not searching for the hole --- limit | |
2823 // search to backing store length. | |
2824 if (static_cast<uint32_t>(elements->length()) < length) { | |
2825 length = elements->length(); | |
2826 } | |
2827 | |
2828 if (!std::isnan(search_value)) { | |
Jakob Kummerow
2016/08/17 15:42:58
Again, reverse the order, just return -1 early in
mattloring
2016/08/18 19:03:10
Done.
| |
2829 for (uint32_t k = start_from; k < length; ++k) { | |
2830 double element_k = elements->get_scalar(k); | |
Jakob Kummerow
2016/08/17 15:42:58
s/double/ctype/; search_value should be of type |c
mattloring
2016/08/18 19:03:11
Done.
| |
2831 if (element_k == search_value) return Just(static_cast<int32_t>(k)); | |
Jakob Kummerow
2016/08/17 15:42:59
Who guarantees that k is in int32_t range?
mattloring
2016/08/18 19:03:10
Done.
| |
2832 } | |
2833 } | |
2834 return Just(-1); | |
2835 } | |
2594 }; | 2836 }; |
2595 | 2837 |
2596 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ | 2838 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ |
2597 typedef TypedElementsAccessor<TYPE##_ELEMENTS, ctype> \ | 2839 typedef TypedElementsAccessor<TYPE##_ELEMENTS, ctype> \ |
2598 Fixed##Type##ElementsAccessor; | 2840 Fixed##Type##ElementsAccessor; |
2599 | 2841 |
2600 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) | 2842 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) |
2601 #undef FIXED_ELEMENTS_ACCESSOR | 2843 #undef FIXED_ELEMENTS_ACCESSOR |
2602 | 2844 |
2603 template <typename Subclass, typename ArgumentsAccessor, typename KindTraits> | 2845 template <typename Subclass, typename ArgumentsAccessor, typename KindTraits> |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2862 if (object->map() != *original_map) { | 3104 if (object->map() != *original_map) { |
2863 // Some mutation occurred in accessor. Abort "fast" path | 3105 // Some mutation occurred in accessor. Abort "fast" path |
2864 return IncludesValueSlowPath(isolate, object, value, k + 1, length); | 3106 return IncludesValueSlowPath(isolate, object, value, k + 1, length); |
2865 } | 3107 } |
2866 } else if (value->SameValueZero(*element_k)) { | 3108 } else if (value->SameValueZero(*element_k)) { |
2867 return Just(true); | 3109 return Just(true); |
2868 } | 3110 } |
2869 } | 3111 } |
2870 return Just(false); | 3112 return Just(false); |
2871 } | 3113 } |
3114 | |
3115 static Maybe<int32_t> IndexOfValueImpl(Isolate* isolate, | |
3116 Handle<JSObject> object, | |
3117 Handle<Object> value, | |
3118 uint32_t start_from, uint32_t length) { | |
3119 DCHECK(JSObject::PrototypeHasNoElements(isolate, *object)); | |
3120 Handle<Map> original_map = handle(object->map(), isolate); | |
3121 FixedArray* parameter_map = FixedArray::cast(object->elements()); | |
3122 | |
3123 for (uint32_t k = start_from; k < length; ++k) { | |
3124 uint32_t entry = | |
3125 GetEntryForIndexImpl(*object, parameter_map, k, ALL_PROPERTIES); | |
3126 if (entry == kMaxUInt32) { | |
3127 continue; | |
3128 } | |
3129 | |
3130 Handle<Object> element_k = GetImpl(parameter_map, entry); | |
3131 | |
3132 if (element_k->IsAccessorPair()) { | |
3133 LookupIterator it(isolate, object, k, LookupIterator::OWN); | |
3134 DCHECK(it.IsFound()); | |
3135 DCHECK_EQ(it.state(), LookupIterator::ACCESSOR); | |
3136 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, element_k, | |
3137 Object::GetPropertyWithAccessor(&it), | |
3138 Nothing<int32_t>()); | |
3139 | |
3140 if (value->StrictEquals(*element_k)) | |
3141 return Just(static_cast<int32_t>(k)); | |
Jakob Kummerow
2016/08/17 15:42:58
nit: braces
mattloring
2016/08/17 23:27:21
Done.
| |
3142 | |
3143 if (object->map() != *original_map) { | |
3144 // Some mutation occurred in accessor. Abort "fast" path | |
Jakob Kummerow
2016/08/17 15:42:58
nit: trailing full stop.
mattloring
2016/08/17 23:27:21
Done.
| |
3145 return IndexOfValueSlowPath(isolate, object, value, k + 1, length); | |
3146 } | |
3147 } else if (value->StrictEquals(*element_k)) { | |
3148 return Just(static_cast<int32_t>(k)); | |
3149 } | |
3150 } | |
3151 return Just(-1); | |
3152 } | |
2872 }; | 3153 }; |
2873 | 3154 |
2874 | 3155 |
2875 class SlowSloppyArgumentsElementsAccessor | 3156 class SlowSloppyArgumentsElementsAccessor |
2876 : public SloppyArgumentsElementsAccessor< | 3157 : public SloppyArgumentsElementsAccessor< |
2877 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, | 3158 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, |
2878 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > { | 3159 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > { |
2879 public: | 3160 public: |
2880 explicit SlowSloppyArgumentsElementsAccessor(const char* name) | 3161 explicit SlowSloppyArgumentsElementsAccessor(const char* name) |
2881 : SloppyArgumentsElementsAccessor< | 3162 : SloppyArgumentsElementsAccessor< |
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3469 insertion_index += len; | 3750 insertion_index += len; |
3470 } | 3751 } |
3471 | 3752 |
3472 DCHECK_EQ(insertion_index, result_len); | 3753 DCHECK_EQ(insertion_index, result_len); |
3473 return result_array; | 3754 return result_array; |
3474 } | 3755 } |
3475 | 3756 |
3476 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 3757 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
3477 } // namespace internal | 3758 } // namespace internal |
3478 } // namespace v8 | 3759 } // namespace v8 |
OLD | NEW |