Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 386cd98498d5181001810ae77cebcf88f24be52b..b763dc45440ab5dfd3ab1296e021d0160645ffb0 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -18997,5 +18997,83 @@ bool JSReceiver::HasProxyInPrototype(Isolate* isolate) { |
return false; |
} |
+Maybe<bool> JSReceiver::IncludesValue(Isolate* isolate, |
+ Handle<JSReceiver> object, |
+ Handle<Object> value, |
+ Handle<Object> from_index) { |
Camillo Bruni
2016/08/01 07:23:47
nit: Any particular reason this has to be on JSRec
caitp
2016/08/01 15:10:45
had moved it here to make it easy to share the c++
|
+ // Let len be ? ToLength(? Get(O, "length")). |
+ int64_t len; |
+ { |
+ Handle<Object> len_; |
+ if (object->map()->instance_type() == JS_ARRAY_TYPE) { |
+ len_ = handle(JSArray::cast(*object)->length(), isolate); |
Camillo Bruni
2016/08/01 07:23:47
nit: A JSArray can only have sane length values (0
caitp
2016/08/01 15:10:45
updated to use ToArrayLength() for JS_ARRAY_TYPE
|
+ } else { |
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
+ isolate, len_, |
+ Object::GetProperty(object, isolate->factory()->length_string()), |
+ Nothing<bool>()); |
+ } |
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
+ isolate, len_, Object::ToLength(isolate, len_), Nothing<bool>()); |
+ len = static_cast<int64_t>(len_->Number()); |
+ DCHECK_EQ(len, len_->Number()); |
+ } |
+ |
+ if (len == 0) return Just(false); |
+ |
+ // Let n be ? ToInteger(fromIndex). (If fromIndex is undefined, this step |
+ // produces the value 0.) |
+ int64_t start_from; |
+ { |
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, from_index, |
+ Object::ToInteger(isolate, from_index), |
+ Nothing<bool>()); |
+ double fp = from_index->Number(); |
+ if (fp > len) return Just(false); |
+ start_from = static_cast<int64_t>(fp); |
+ } |
+ |
+ int64_t index; |
+ if (start_from >= 0) { |
+ index = start_from; |
+ } else { |
+ index = len + start_from; |
+ if (index < 0) { |
+ index = 0; |
+ } |
+ } |
+ |
+ // If the receiver is not a special receiver type, and the length is a valid |
+ // element index, perform fast operation tailored to specific ElementsKinds. |
+ if (object->map()->instance_type() > LAST_SPECIAL_RECEIVER_TYPE && |
+ len < kMaxUInt32 && |
+ JSObject::PrototypeHasNoElements(isolate, JSObject::cast(*object))) { |
+ Handle<JSObject> obj = Handle<JSObject>::cast(object); |
+ ElementsAccessor* elements = obj->GetElementsAccessor(); |
+ return elements->IncludesValue(isolate, obj, value, |
+ static_cast<uint32_t>(index), |
+ static_cast<uint32_t>(len)); |
+ } |
+ |
+ // Otherwise, perform slow lookups for special receiver types |
+ for (; index < len; ++index) { |
+ // Let elementK be the result of ? Get(O, ! ToString(k)). |
+ Handle<Object> element_k; |
+ { |
+ Handle<Object> index_obj = isolate->factory()->NewNumberFromInt64(index); |
+ bool success; |
+ LookupIterator it = LookupIterator::PropertyOrElement( |
+ isolate, object, index_obj, &success); |
+ DCHECK(success); |
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
+ isolate, element_k, Object::GetProperty(&it), Nothing<bool>()); |
+ } |
+ |
+ // If SameValueZero(searchElement, elementK) is true, return true. |
+ if (value->SameValueZero(*element_k)) return Just(true); |
+ } |
+ return Just(false); |
+} |
+ |
} // namespace internal |
} // namespace v8 |