| Index: src/runtime/runtime-array.cc | 
| diff --git a/src/runtime/runtime-array.cc b/src/runtime/runtime-array.cc | 
| index a92215c85d046ab8121dab8248d336c96e55fe15..64c95935268764cc8bcaebd3d76e986119891fb7 100644 | 
| --- a/src/runtime/runtime-array.cc | 
| +++ b/src/runtime/runtime-array.cc | 
| @@ -32,18 +32,24 @@ RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) { | 
| } | 
|  | 
| static void InstallCode(Isolate* isolate, Handle<JSObject> holder, | 
| -                        const char* name, Handle<Code> code) { | 
| +                        const char* name, Handle<Code> code, int argc = -1) { | 
| Handle<String> key = isolate->factory()->InternalizeUtf8String(name); | 
| Handle<JSFunction> optimized = | 
| isolate->factory()->NewFunctionWithoutPrototype(key, code); | 
| -  optimized->shared()->DontAdaptArguments(); | 
| +  if (argc < 0) { | 
| +    optimized->shared()->DontAdaptArguments(); | 
| +  } else { | 
| +    optimized->shared()->set_internal_formal_parameter_count(argc); | 
| +  } | 
| JSObject::AddProperty(holder, key, optimized, NONE); | 
| } | 
|  | 
| static void InstallBuiltin(Isolate* isolate, Handle<JSObject> holder, | 
| -                           const char* name, Builtins::Name builtin_name) { | 
| +                           const char* name, Builtins::Name builtin_name, | 
| +                           int argc = -1) { | 
| InstallCode(isolate, holder, name, | 
| -              handle(isolate->builtins()->builtin(builtin_name), isolate)); | 
| +              handle(isolate->builtins()->builtin(builtin_name), isolate), | 
| +              argc); | 
| } | 
|  | 
| RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) { | 
| @@ -59,6 +65,7 @@ RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) { | 
| InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift); | 
| InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice); | 
| InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice); | 
| +  InstallBuiltin(isolate, holder, "includes", Builtins::kArrayIncludes, 2); | 
|  | 
| return *holder; | 
| } | 
| @@ -438,5 +445,91 @@ RUNTIME_FUNCTION(Runtime_ArraySpeciesConstructor) { | 
| isolate, Object::ArraySpeciesConstructor(isolate, original_array)); | 
| } | 
|  | 
| +// ES7 22.1.3.11 Array.prototype.includes | 
| +RUNTIME_FUNCTION(Runtime_ArrayIncludes_Slow) { | 
| +  HandleScope shs(isolate); | 
| +  DCHECK(args.length() == 3); | 
| +  CONVERT_ARG_HANDLE_CHECKED(Object, search_element, 1); | 
| +  CONVERT_ARG_HANDLE_CHECKED(Object, from_index_, 2); | 
| + | 
| +  // 1. Let O be ? ToObject(this value). | 
| +  Handle<JSReceiver> object; | 
| +  ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
| +      isolate, object, Object::ToObject(isolate, handle(args[0], isolate))); | 
| + | 
| +  // 2. Let len be ? ToLength(? Get(O, "length")). | 
| +  Handle<Object> len_; | 
| +  Handle<String> length_string = | 
| +      handle(isolate->heap()->length_string(), isolate); | 
| +  ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
| +      isolate, len_, Object::GetProperty(object, length_string)); | 
| +  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, len_, | 
| +                                     Object::ToLength(isolate, len_)); | 
| +  int64_t len = static_cast<int64_t>(len_->Number()); | 
| +  DCHECK_EQ(len, len_->Number()); | 
| + | 
| +  // 3. If len is 0, return false. | 
| +  if (len == 0) return isolate->heap()->false_value(); | 
| + | 
| +  // 4. Let n be ? ToInteger(fromIndex). (If fromIndex is undefined, | 
| +  //    this step produces the value 0.) | 
| +  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, from_index_, | 
| +                                     Object::ToInteger(isolate, from_index_)); | 
| +  if (std::isinf(from_index_->Number()) && from_index_->Number() > 0.0) { | 
| +    return isolate->heap()->false_value(); | 
| +  } | 
| +  int64_t from_index = static_cast<int64_t>(from_index_->Number()); | 
| + | 
| +  int64_t k; | 
| +  if (from_index >= 0) { | 
| +    k = from_index; | 
| +  } else { | 
| +    k = len + from_index; | 
| +    if (k < 0) { | 
| +      k = 0; | 
| +    } | 
| +  } | 
| + | 
| +  if (IsFastPackedElementsKind(object->map()->elements_kind()) && | 
| +      len < std::numeric_limits<uint32_t>::max()) { | 
| +    uint32_t i = static_cast<uint32_t>(k); | 
| +    for (; i < static_cast<uint32_t>(len); ++i) { | 
| +      Handle<Object> element_k; | 
| +      ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
| +          isolate, element_k, Object::GetElement(isolate, object, i)); | 
| +      if (search_element->SameValueZero(*element_k)) { | 
| +        return isolate->heap()->true_value(); | 
| +      } | 
| +    } | 
| +    return isolate->heap()->false_value(); | 
| +  } | 
| + | 
| +  bool stable = !object->IsJSProxy() && | 
| +                IsFastElementsKind(object->map()->elements_kind()); | 
| +  Handle<Map> original_map = handle(object->map(), isolate); | 
| +  for (; k < len; ++k) { | 
| +    Handle<Object> element_k; | 
| +    if (stable && k < std::numeric_limits<uint32_t>::max()) { | 
| +      uint32_t index = static_cast<uint32_t>(k); | 
| +      ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
| +          isolate, element_k, Object::GetElement(isolate, object, index)); | 
| +      stable = object->map() == *original_map; | 
| +    } else { | 
| +      Handle<String> name; | 
| +      Handle<Object> num = | 
| +          isolate->factory()->NewNumber(static_cast<double>(k)); | 
| +      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, | 
| +                                         Object::ToString(isolate, num)); | 
| +      ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
| +          isolate, element_k, Object::GetPropertyOrElement(object, name)); | 
| +    } | 
| + | 
| +    if (search_element->SameValueZero(*element_k)) { | 
| +      return isolate->heap()->true_value(); | 
| +    } | 
| +  } | 
| +  return isolate->heap()->false_value(); | 
| +} | 
| + | 
| }  // namespace internal | 
| }  // namespace v8 | 
|  |