| Index: src/objects.cc
 | 
| diff --git a/src/objects.cc b/src/objects.cc
 | 
| index cb47e5766d182758868db7e37ffa2604cb274349..ea3649198e1e77b8e1adbfdb4c10f2e000329816 100644
 | 
| --- a/src/objects.cc
 | 
| +++ b/src/objects.cc
 | 
| @@ -116,6 +116,17 @@ MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate,
 | 
|    return result;
 | 
|  }
 | 
|  
 | 
| +// ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
 | 
| +// static
 | 
| +MaybeHandle<JSReceiver> Object::ConvertReceiver(Isolate* isolate,
 | 
| +                                                Handle<Object> object) {
 | 
| +  if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
 | 
| +  if (*object == isolate->heap()->null_value() ||
 | 
| +      *object == isolate->heap()->undefined_value()) {
 | 
| +    return isolate->global_proxy();
 | 
| +  }
 | 
| +  return Object::ToObject(isolate, object);
 | 
| +}
 | 
|  
 | 
|  // static
 | 
|  MaybeHandle<Object> Object::ToNumber(Handle<Object> input) {
 | 
| @@ -6135,7 +6146,9 @@ Maybe<bool> JSReceiver::DeletePropertyOrElement(Handle<JSReceiver> object,
 | 
|  
 | 
|  
 | 
|  // ES6 7.1.14
 | 
| -MaybeHandle<Object> ToPropertyKey(Isolate* isolate, Handle<Object> value) {
 | 
| +// static
 | 
| +MaybeHandle<Object> Object::ToPropertyKey(Isolate* isolate,
 | 
| +                                          Handle<Object> value) {
 | 
|    // 1. Let key be ToPrimitive(argument, hint String).
 | 
|    MaybeHandle<Object> maybe_key =
 | 
|        Object::ToPrimitive(value, ToPrimitiveHint::kString);
 | 
| @@ -8919,53 +8932,6 @@ MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
 | 
|    return object;
 | 
|  }
 | 
|  
 | 
| -
 | 
| -MaybeHandle<Object> JSObject::GetAccessor(Handle<JSObject> object,
 | 
| -                                          Handle<Name> name,
 | 
| -                                          AccessorComponent component) {
 | 
| -  Isolate* isolate = object->GetIsolate();
 | 
| -
 | 
| -  // Make sure that the top context does not change when doing callbacks or
 | 
| -  // interceptor calls.
 | 
| -  AssertNoContextChange ncc(isolate);
 | 
| -
 | 
| -  LookupIterator it = LookupIterator::PropertyOrElement(
 | 
| -      isolate, object, name, LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
 | 
| -
 | 
| -  for (; it.IsFound(); it.Next()) {
 | 
| -    switch (it.state()) {
 | 
| -      case LookupIterator::INTERCEPTOR:
 | 
| -      case LookupIterator::NOT_FOUND:
 | 
| -      case LookupIterator::TRANSITION:
 | 
| -        UNREACHABLE();
 | 
| -
 | 
| -      case LookupIterator::ACCESS_CHECK:
 | 
| -        if (it.HasAccess()) continue;
 | 
| -        isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>());
 | 
| -        RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
 | 
| -        return isolate->factory()->undefined_value();
 | 
| -
 | 
| -      case LookupIterator::JSPROXY:
 | 
| -        return isolate->factory()->undefined_value();
 | 
| -
 | 
| -      case LookupIterator::INTEGER_INDEXED_EXOTIC:
 | 
| -        return isolate->factory()->undefined_value();
 | 
| -      case LookupIterator::DATA:
 | 
| -        continue;
 | 
| -      case LookupIterator::ACCESSOR: {
 | 
| -        Handle<Object> maybe_pair = it.GetAccessors();
 | 
| -        if (maybe_pair->IsAccessorPair()) {
 | 
| -          return AccessorPair::GetComponent(
 | 
| -              Handle<AccessorPair>::cast(maybe_pair), component);
 | 
| -        }
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  return isolate->factory()->undefined_value();
 | 
| -}
 | 
| -
 | 
| -
 | 
|  Object* JSObject::SlowReverseLookup(Object* value) {
 | 
|    if (HasFastProperties()) {
 | 
|      int number_of_own_descriptors = map()->NumberOfOwnDescriptors();
 | 
| @@ -15782,20 +15748,6 @@ bool JSObject::WasConstructedFromApiFunction() {
 | 
|    return is_api_object;
 | 
|  }
 | 
|  
 | 
| -int JSObject::NumberOfOwnElements(PropertyFilter filter) {
 | 
| -  // Fast case for objects with no elements.
 | 
| -  if (!IsJSValue() && HasFastElements()) {
 | 
| -    uint32_t length =
 | 
| -        IsJSArray()
 | 
| -            ? static_cast<uint32_t>(
 | 
| -                  Smi::cast(JSArray::cast(this)->length())->value())
 | 
| -            : static_cast<uint32_t>(FixedArrayBase::cast(elements())->length());
 | 
| -    if (length == 0) return 0;
 | 
| -  }
 | 
| -  // Compute the number of enumerable elements.
 | 
| -  return GetOwnElementKeys(NULL, filter);
 | 
| -}
 | 
| -
 | 
|  void JSObject::CollectOwnElementKeys(Handle<JSObject> object,
 | 
|                                       KeyAccumulator* keys,
 | 
|                                       PropertyFilter filter) {
 | 
| @@ -15805,139 +15757,6 @@ void JSObject::CollectOwnElementKeys(Handle<JSObject> object,
 | 
|  }
 | 
|  
 | 
|  
 | 
| -int JSObject::GetOwnElementKeys(FixedArray* storage, PropertyFilter filter) {
 | 
| -  int counter = 0;
 | 
| -
 | 
| -  // If this is a String wrapper, add the string indices first,
 | 
| -  // as they're guaranteed to precede the elements in numerical order
 | 
| -  // and ascending order is required by ECMA-262, 6th, 9.1.12.
 | 
| -  if (IsJSValue()) {
 | 
| -    Object* val = JSValue::cast(this)->value();
 | 
| -    if (val->IsString()) {
 | 
| -      String* str = String::cast(val);
 | 
| -      if (storage) {
 | 
| -        for (int i = 0; i < str->length(); i++) {
 | 
| -          storage->set(counter + i, Smi::FromInt(i));
 | 
| -        }
 | 
| -      }
 | 
| -      counter += str->length();
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  switch (GetElementsKind()) {
 | 
| -    case FAST_SMI_ELEMENTS:
 | 
| -    case FAST_ELEMENTS:
 | 
| -    case FAST_HOLEY_SMI_ELEMENTS:
 | 
| -    case FAST_HOLEY_ELEMENTS:
 | 
| -    case FAST_STRING_WRAPPER_ELEMENTS: {
 | 
| -      int length = IsJSArray() ?
 | 
| -          Smi::cast(JSArray::cast(this)->length())->value() :
 | 
| -          FixedArray::cast(elements())->length();
 | 
| -      for (int i = 0; i < length; i++) {
 | 
| -        if (!FixedArray::cast(elements())->get(i)->IsTheHole()) {
 | 
| -          if (storage != NULL) {
 | 
| -            storage->set(counter, Smi::FromInt(i));
 | 
| -          }
 | 
| -          counter++;
 | 
| -        }
 | 
| -      }
 | 
| -      DCHECK(!storage || storage->length() >= counter);
 | 
| -      break;
 | 
| -    }
 | 
| -    case FAST_DOUBLE_ELEMENTS:
 | 
| -    case FAST_HOLEY_DOUBLE_ELEMENTS: {
 | 
| -      int length = IsJSArray() ?
 | 
| -          Smi::cast(JSArray::cast(this)->length())->value() :
 | 
| -          FixedArrayBase::cast(elements())->length();
 | 
| -      for (int i = 0; i < length; i++) {
 | 
| -        if (!FixedDoubleArray::cast(elements())->is_the_hole(i)) {
 | 
| -          if (storage != NULL) {
 | 
| -            storage->set(counter, Smi::FromInt(i));
 | 
| -          }
 | 
| -          counter++;
 | 
| -        }
 | 
| -      }
 | 
| -      DCHECK(!storage || storage->length() >= counter);
 | 
| -      break;
 | 
| -    }
 | 
| -
 | 
| -#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                      \
 | 
| -    case TYPE##_ELEMENTS:                                                    \
 | 
| -
 | 
| -    TYPED_ARRAYS(TYPED_ARRAY_CASE)
 | 
| -#undef TYPED_ARRAY_CASE
 | 
| -    {
 | 
| -      int length = FixedArrayBase::cast(elements())->length();
 | 
| -      while (counter < length) {
 | 
| -        if (storage != NULL) {
 | 
| -          storage->set(counter, Smi::FromInt(counter));
 | 
| -        }
 | 
| -        counter++;
 | 
| -      }
 | 
| -      DCHECK(!storage || storage->length() >= counter);
 | 
| -      break;
 | 
| -    }
 | 
| -
 | 
| -    case DICTIONARY_ELEMENTS:
 | 
| -    case SLOW_STRING_WRAPPER_ELEMENTS: {
 | 
| -      if (storage != NULL) {
 | 
| -        element_dictionary()->CopyKeysTo(storage, counter, filter,
 | 
| -                                         SeededNumberDictionary::SORTED);
 | 
| -      }
 | 
| -      counter += element_dictionary()->NumberOfElementsFilterAttributes(filter);
 | 
| -      break;
 | 
| -    }
 | 
| -    case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
 | 
| -    case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
 | 
| -      FixedArray* parameter_map = FixedArray::cast(elements());
 | 
| -      int mapped_length = parameter_map->length() - 2;
 | 
| -      FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
 | 
| -      if (arguments->IsDictionary()) {
 | 
| -        // Copy the keys from arguments first, because Dictionary::CopyKeysTo
 | 
| -        // will insert in storage starting at index 0.
 | 
| -        SeededNumberDictionary* dictionary =
 | 
| -            SeededNumberDictionary::cast(arguments);
 | 
| -        if (storage != NULL) {
 | 
| -          dictionary->CopyKeysTo(storage, counter, filter,
 | 
| -                                 SeededNumberDictionary::UNSORTED);
 | 
| -        }
 | 
| -        counter += dictionary->NumberOfElementsFilterAttributes(filter);
 | 
| -        for (int i = 0; i < mapped_length; ++i) {
 | 
| -          if (!parameter_map->get(i + 2)->IsTheHole()) {
 | 
| -            if (storage != NULL) storage->set(counter, Smi::FromInt(i));
 | 
| -            ++counter;
 | 
| -          }
 | 
| -        }
 | 
| -        if (storage != NULL) storage->SortPairs(storage, counter);
 | 
| -
 | 
| -      } else {
 | 
| -        int backing_length = arguments->length();
 | 
| -        int i = 0;
 | 
| -        for (; i < mapped_length; ++i) {
 | 
| -          if (!parameter_map->get(i + 2)->IsTheHole()) {
 | 
| -            if (storage != NULL) storage->set(counter, Smi::FromInt(i));
 | 
| -            ++counter;
 | 
| -          } else if (i < backing_length && !arguments->get(i)->IsTheHole()) {
 | 
| -            if (storage != NULL) storage->set(counter, Smi::FromInt(i));
 | 
| -            ++counter;
 | 
| -          }
 | 
| -        }
 | 
| -        for (; i < backing_length; ++i) {
 | 
| -          if (storage != NULL) storage->set(counter, Smi::FromInt(i));
 | 
| -          ++counter;
 | 
| -        }
 | 
| -      }
 | 
| -      break;
 | 
| -    }
 | 
| -    case NO_ELEMENTS:
 | 
| -      break;
 | 
| -  }
 | 
| -
 | 
| -  DCHECK(!storage || storage->length() == counter);
 | 
| -  return counter;
 | 
| -}
 | 
| -
 | 
| -
 | 
|  MaybeHandle<String> Object::ObjectProtoToString(Isolate* isolate,
 | 
|                                                  Handle<Object> object) {
 | 
|    if (object->IsUndefined()) return isolate->factory()->undefined_to_string();
 | 
| @@ -17781,30 +17600,6 @@ void Dictionary<Derived, Shape, Key>::CopyEnumKeysTo(FixedArray* storage) {
 | 
|    }
 | 
|  }
 | 
|  
 | 
| -
 | 
| -template <typename Derived, typename Shape, typename Key>
 | 
| -int Dictionary<Derived, Shape, Key>::CopyKeysTo(
 | 
| -    FixedArray* storage, int index, PropertyFilter filter,
 | 
| -    typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) {
 | 
| -  DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter));
 | 
| -  int start_index = index;
 | 
| -  int capacity = this->Capacity();
 | 
| -  for (int i = 0; i < capacity; i++) {
 | 
| -    Object* k = this->KeyAt(i);
 | 
| -    if (!this->IsKey(k) || k->FilterKey(filter)) continue;
 | 
| -    if (this->IsDeleted(i)) continue;
 | 
| -    PropertyDetails details = this->DetailsAt(i);
 | 
| -    PropertyAttributes attr = details.attributes();
 | 
| -    if ((attr & filter) != 0) continue;
 | 
| -    storage->set(index++, k);
 | 
| -  }
 | 
| -  if (sort_mode == Dictionary::SORTED) {
 | 
| -    storage->SortPairs(storage, index);
 | 
| -  }
 | 
| -  DCHECK(storage->length() >= index);
 | 
| -  return index - start_index;
 | 
| -}
 | 
| -
 | 
|  template <typename Derived, typename Shape, typename Key>
 | 
|  void Dictionary<Derived, Shape, Key>::CollectKeysTo(
 | 
|      Handle<Dictionary<Derived, Shape, Key> > dictionary, KeyAccumulator* keys,
 | 
| 
 |