Chromium Code Reviews| 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 |