Index: src/elements.cc |
diff --git a/src/elements.cc b/src/elements.cc |
index 7a12f6606516f78d8ae0a7bffbd54654b0cd84c7..ac9fc1ef741eeba5685be1986d4edb3763b278c6 100644 |
--- a/src/elements.cc |
+++ b/src/elements.cc |
@@ -1219,6 +1219,19 @@ class ElementsAccessorBase : public ElementsAccessor { |
length); |
} |
+ static Maybe<int64_t> LastIndexOfValueImpl(Isolate* isolate, |
+ Handle<JSObject> receiver, |
+ Handle<Object> value, |
+ int64_t start_from) { |
+ UNREACHABLE(); |
+ } |
+ |
+ Maybe<int64_t> LastIndexOfValue(Isolate* isolate, Handle<JSObject> receiver, |
+ Handle<Object> value, |
+ int64_t start_from) final { |
+ return Subclass::LastIndexOfValueImpl(isolate, receiver, value, start_from); |
+ } |
+ |
static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, |
uint32_t entry) { |
return entry; |
@@ -2915,6 +2928,45 @@ class TypedElementsAccessor |
} |
return Just<int64_t>(-1); |
} |
+ |
+ static Maybe<int64_t> LastIndexOfValueImpl(Isolate* isolate, |
+ Handle<JSObject> receiver, |
+ Handle<Object> value, |
+ int64_t start_from) { |
+ DisallowHeapAllocation no_gc; |
Camillo Bruni
2017/03/14 09:58:21
I think we can just do
DCHECK(WasNeutered(*receive
Choongwoo Han
2017/03/14 16:12:31
Done.
|
+ |
+ if (WasNeutered(*receiver) || !value->IsNumber()) return Just<int64_t>(-1); |
+ BackingStore* elements = BackingStore::cast(receiver->elements()); |
+ |
+ double search_value = value->Number(); |
+ |
+ if (!std::isfinite(search_value)) { |
+ if (!std::is_integral<ctype>::value) { |
+ // Integral types cannot represent +Inf or NaN. |
+ return Just<int64_t>(-1); |
+ } else if (std::isnan(search_value)) { |
+ // Strict Equality Comparison of NaN is always false. |
+ return Just<int64_t>(-1); |
+ } |
+ } else if (search_value < std::numeric_limits<ctype>::lowest() || |
+ search_value > std::numeric_limits<ctype>::max()) { |
+ // Return -1 if value can't be represented in this ElementsKind. |
+ return Just<int64_t>(-1); |
+ } |
+ |
+ ctype typed_search_value = static_cast<ctype>(search_value); |
+ if (static_cast<double>(typed_search_value) != search_value) { |
+ return Just<int64_t>(-1); // Loss of precision. |
+ } |
+ |
+ DCHECK_LT(start_from, elements->length()); |
+ |
+ for (int64_t k = start_from; k >= 0; --k) { |
+ ctype element_k = elements->get_scalar(k); |
+ if (element_k == typed_search_value) return Just<int64_t>(k); |
+ } |
+ return Just<int64_t>(-1); |
+ } |
}; |
#define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ |