Revision: 22482
Author:   [email protected]
Date:     Fri Jul 18 13:47:25 2014 UTC
Log:      Reimplement SetProperty using the LookupIterator

BUG=
[email protected]

Review URL: https://codereview.chromium.org/392243002
http://code.google.com/p/v8/source/detail?r=22482

Modified:
 /branches/bleeding_edge/src/debug.cc
 /branches/bleeding_edge/src/ic.cc
 /branches/bleeding_edge/src/lookup.cc
 /branches/bleeding_edge/src/lookup.h
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/src/stub-cache.cc
 /branches/bleeding_edge/src/v8natives.js
 /branches/bleeding_edge/test/cctest/test-decls.cc

=======================================
--- /branches/bleeding_edge/src/debug.cc        Wed Jul 16 12:18:33 2014 UTC
+++ /branches/bleeding_edge/src/debug.cc        Fri Jul 18 13:47:25 2014 UTC
@@ -1547,7 +1547,7 @@
     if (is_load_or_store) {
// Remember source position and frame to handle step in getter/setter. If
       // there is a custom getter/setter it will be handled in
- // Object::Get/SetPropertyWithCallback, otherwise the step action will be + // Object::Get/SetPropertyWithAccessor, otherwise the step action will be
       // propagated on the next Debug::Break.
       thread_local_.last_statement_position_ =
           debug_info->code()->SourceStatementPosition(frame->pc());
=======================================
--- /branches/bleeding_edge/src/ic.cc   Thu Jul 17 09:44:37 2014 UTC
+++ /branches/bleeding_edge/src/ic.cc   Fri Jul 18 13:47:25 2014 UTC
@@ -1281,6 +1281,8 @@
                                    Handle<String> name,
                                    Handle<Object> value,
                                    JSReceiver::StoreFromKeyed store_mode) {
+ // TODO(verwaest): Let SetProperty do the migration, since storing a property
+  // might deprecate the current map again, if value does not fit.
   if (MigrateDeprecated(object) || object->IsJSProxy()) {
     Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
     Handle<Object> result;
@@ -1757,6 +1759,8 @@
 MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
                                         Handle<Object> key,
                                         Handle<Object> value) {
+ // TODO(verwaest): Let SetProperty do the migration, since storing a property
+  // might deprecate the current map again, if value does not fit.
   if (MigrateDeprecated(object)) {
     Handle<Object> result;
     ASSIGN_RETURN_ON_EXCEPTION(
=======================================
--- /branches/bleeding_edge/src/lookup.cc       Thu Jul 17 09:06:49 2014 UTC
+++ /branches/bleeding_edge/src/lookup.cc       Fri Jul 18 13:47:25 2014 UTC
@@ -142,6 +142,78 @@
   has_property_ = true;
   return true;
 }
+
+
+void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
+  ASSERT(has_property_);
+  ASSERT(HolderIsReceiver());
+  if (property_encoding_ == DICTIONARY) return;
+  holder_map_ = Map::PrepareForDataProperty(holder_map_, number_, value);
+  JSObject::MigrateToMap(GetHolder(), holder_map_);
+  // Reload property information.
+  if (holder_map_->is_dictionary_map()) {
+    property_encoding_ = DICTIONARY;
+  } else {
+    property_encoding_ = DESCRIPTOR;
+  }
+  CHECK(HasProperty());
+}
+
+
+void LookupIterator::TransitionToDataProperty(
+    Handle<Object> value, PropertyAttributes attributes,
+    Object::StoreFromKeyed store_mode) {
+  ASSERT(!has_property_ || !HolderIsReceiver());
+
+  // Can only be called when the receiver is a JSObject. JSProxy has to be
+  // handled via a trap. Adding properties to primitive values is not
+  // observable.
+  Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver());
+
+  // Properties have to be added to context extension objects through
+  // SetOwnPropertyIgnoreAttributes.
+  ASSERT(!receiver->IsJSContextExtensionObject());
+
+  if (receiver->IsJSGlobalProxy()) {
+    PrototypeIterator iter(isolate(), receiver);
+    receiver =
+        Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter));
+  }
+
+  maybe_holder_ = receiver;
+ holder_map_ = Map::TransitionToDataProperty(handle(receiver->map()), name_, + value, attributes, store_mode);
+  JSObject::MigrateToMap(receiver, holder_map_);
+
+  // Reload the information.
+  state_ = NOT_FOUND;
+  configuration_ = CHECK_OWN_REAL;
+  state_ = LookupInHolder();
+  ASSERT(IsFound());
+  HasProperty();
+}
+
+
+bool LookupIterator::HolderIsReceiver() const {
+  ASSERT(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY);
+  DisallowHeapAllocation no_gc;
+  Handle<Object> receiver = GetReceiver();
+  if (!receiver->IsJSReceiver()) return false;
+  Object* current = *receiver;
+  JSReceiver* holder = *maybe_holder_.ToHandleChecked();
+  // JSProxy do not occur as hidden prototypes.
+  if (current->IsJSProxy()) {
+    return JSReceiver::cast(current) == holder;
+  }
+  PrototypeIterator iter(isolate(), current,
+                         PrototypeIterator::START_AT_RECEIVER);
+  do {
+    if (JSReceiver::cast(iter.GetCurrent()) == holder) return true;
+    ASSERT(!current->IsJSProxy());
+    iter.Advance();
+  } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
+  return false;
+}


 Handle<Object> LookupIterator::FetchValue() const {
@@ -181,4 +253,29 @@
 }


+void LookupIterator::WriteDataValue(Handle<Object> value) {
+  ASSERT(is_guaranteed_to_have_holder());
+  ASSERT(has_property_);
+  if (property_encoding_ == DICTIONARY) {
+    Handle<JSObject> holder = GetHolder();
+    NameDictionary* property_dictionary = holder->property_dictionary();
+    if (holder->IsGlobalObject()) {
+      Handle<PropertyCell> cell(
+          PropertyCell::cast(property_dictionary->ValueAt(number_)));
+      PropertyCell::SetValueInferType(cell, value);
+    } else {
+      property_dictionary->ValueAtPut(number_, *value);
+    }
+  } else if (property_details_.type() == v8::internal::FIELD) {
+    GetHolder()->WriteToField(number_, *value);
+  } else {
+    ASSERT_EQ(v8::internal::CONSTANT, property_details_.type());
+  }
+}
+
+
+void LookupIterator::InternalizeName() {
+  if (name_->IsUniqueName()) return;
+  name_ = factory()->InternalizeString(Handle<String>::cast(name_));
+}
 } }  // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/lookup.h        Thu Jun 12 15:08:33 2014 UTC
+++ /branches/bleeding_edge/src/lookup.h        Fri Jul 18 13:47:25 2014 UTC
@@ -92,11 +92,13 @@
   Handle<Object> GetReceiver() const {
     return Handle<Object>::cast(maybe_receiver_.ToHandleChecked());
   }
+  Handle<Map> holder_map() const { return holder_map_; }
   Handle<JSObject> GetHolder() const {
     ASSERT(IsFound() && state_ != JSPROXY);
     return Handle<JSObject>::cast(maybe_holder_.ToHandleChecked());
   }
   Handle<JSReceiver> GetRoot() const;
+  bool HolderIsReceiver() const;

   /* Dynamically reduce the trapped types. */
   void skip_interceptor() {
@@ -116,6 +118,10 @@
   // below can be used. It ensures that we are able to provide a definite
   // answer, and loads extra information about the property.
   bool HasProperty();
+  void PrepareForDataProperty(Handle<Object> value);
+  void TransitionToDataProperty(Handle<Object> value,
+                                PropertyAttributes attributes,
+                                Object::StoreFromKeyed store_mode);
   PropertyKind property_kind() const {
     ASSERT(has_property_);
     return property_kind_;
@@ -124,11 +130,18 @@
     ASSERT(has_property_);
     return property_details_;
   }
+  int descriptor_number() const {
+    ASSERT(has_property_);
+    ASSERT_EQ(DESCRIPTOR, property_encoding_);
+    return number_;
+  }
   Handle<Object> GetAccessors() const;
   Handle<Object> GetDataValue() const;
+  void WriteDataValue(Handle<Object> value);
+
+  void InternalizeName();

   /* JSPROXY */
-
   Handle<JSProxy> GetJSProxy() const {
     return Handle<JSProxy>::cast(maybe_holder_.ToHandleChecked());
   }
=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Thu Jul 17 09:44:37 2014 UTC
+++ /branches/bleeding_edge/src/objects-inl.h   Fri Jul 18 13:47:25 2014 UTC
@@ -2079,23 +2079,12 @@
 }


-bool JSObject::TooManyFastProperties(StoreFromKeyed store_mode) {
-  // Allow extra fast properties if the object has more than
- // kFastPropertiesSoftLimit in-object properties. When this is the case, it is - // very unlikely that the object is being used as a dictionary and there is a
-  // good chance that allowing more map transitions will be worth it.
-  Map* map = this->map();
-  if (map->unused_property_fields() != 0) return false;
-
-  int inobject = map->inobject_properties();
-
-  int limit;
-  if (store_mode == CERTAINLY_NOT_STORE_FROM_KEYED) {
-    limit = Max(inobject, kMaxFastProperties);
-  } else {
-    limit = Max(inobject, kFastPropertiesSoftLimit);
-  }
-  return properties()->length() > limit;
+bool Map::TooManyFastProperties(StoreFromKeyed store_mode) {
+  if (unused_property_fields() != 0) return false;
+  int minimum = store_mode == CERTAINLY_NOT_STORE_FROM_KEYED ? 128 : 12;
+  int limit = Max(minimum, inobject_properties());
+  int external = NumberOfFields() - inobject_properties();
+  return external > limit;
 }


=======================================
--- /branches/bleeding_edge/src/objects.cc      Fri Jul 18 07:17:21 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc      Fri Jul 18 13:47:25 2014 UTC
@@ -462,12 +462,9 @@
 }


-MaybeHandle<Object> Object::SetPropertyWithCallback(Handle<Object> receiver,
-                                                    Handle<Name> name,
-                                                    Handle<Object> value,
- Handle<JSObject> holder, - Handle<Object> structure, - StrictMode strict_mode) {
+MaybeHandle<Object> Object::SetPropertyWithAccessor(
+    Handle<Object> receiver, Handle<Name> name, Handle<Object> value,
+ Handle<JSObject> holder, Handle<Object> structure, StrictMode strict_mode) {
   Isolate* isolate = name->GetIsolate();

   // We should never get here to initialize a const with the hole
@@ -605,48 +602,33 @@
 }


-static bool FindAllCanWriteHolder(LookupResult* result,
-                                  Handle<Name> name,
-                                  bool check_prototype) {
-  if (result->IsInterceptor()) {
-    result->holder()->LookupOwnRealNamedProperty(name, result);
-  }
-
-  while (result->IsProperty()) {
-    if (result->type() == CALLBACKS) {
-      Object* callback_obj = result->GetCallbackObject();
-      if (callback_obj->IsAccessorInfo()) {
-        if (AccessorInfo::cast(callback_obj)->all_can_write()) return true;
+static bool FindAllCanWriteHolder(LookupIterator* it) {
+  it->skip_interceptor();
+  it->skip_access_check();
+  for (; it->IsFound(); it->Next()) {
+    if (it->state() == LookupIterator::PROPERTY && it->HasProperty() &&
+        it->property_kind() == LookupIterator::ACCESSOR) {
+      Handle<Object> accessors = it->GetAccessors();
+      if (accessors->IsAccessorInfo()) {
+        if (AccessorInfo::cast(*accessors)->all_can_write()) return true;
       }
     }
-    if (!check_prototype) break;
-    result->holder()->LookupRealNamedPropertyInPrototypes(name, result);
   }
   return false;
 }


 MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck(
-    Handle<JSObject> object,
-    LookupResult* result,
-    Handle<Name> name,
-    Handle<Object> value,
-    bool check_prototype,
-    StrictMode strict_mode) {
-  if (check_prototype && !result->IsProperty()) {
-    object->LookupRealNamedPropertyInPrototypes(name, result);
-  }
-
-  if (FindAllCanWriteHolder(result, name, check_prototype)) {
-    Handle<JSObject> holder(result->holder());
- Handle<Object> callbacks(result->GetCallbackObject(), result->isolate());
-    return SetPropertyWithCallback(
-        object, name, value, holder, callbacks, strict_mode);
+    LookupIterator* it, Handle<Object> value, StrictMode strict_mode) {
+  Handle<JSObject> checked = Handle<JSObject>::cast(it->GetHolder());
+  if (FindAllCanWriteHolder(it)) {
+    return SetPropertyWithAccessor(it->GetReceiver(), it->name(), value,
+                                   it->GetHolder(), it->GetAccessors(),
+                                   strict_mode);
   }

-  Isolate* isolate = object->GetIsolate();
-  isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET);
-  RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
+  it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_SET);
+  RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
   return value;
 }

@@ -1835,7 +1817,7 @@
   if (value->IsJSFunction()) {
     maybe_map = Map::CopyWithConstant(
         handle(object->map()), name, value, attributes, flag);
-  } else if (!object->TooManyFastProperties(store_mode)) {
+  } else if (!object->map()->TooManyFastProperties(store_mode)) {
     Isolate* isolate = object->GetIsolate();
     Representation representation = value->OptimalRepresentation();
     maybe_map = Map::CopyWithField(
@@ -1967,23 +1949,6 @@
                   isolate->factory()->undefined_value(),
                   argc, args).Assert();
 }
-
-
-MaybeHandle<Object> JSObject::SetPropertyPostInterceptor(
-    Handle<JSObject> object,
-    Handle<Name> name,
-    Handle<Object> value,
-    StrictMode strict_mode) {
-  // Check own property, ignore interceptor.
-  Isolate* isolate = object->GetIsolate();
-  LookupResult result(isolate);
-  object->LookupOwnRealNamedProperty(name, &result);
-  if (!result.IsFound()) {
-    object->map()->LookupTransition(*object, *name, &result);
-  }
-  return SetPropertyForResult(object, &result, name, value, strict_mode,
-                              MAY_BE_STORE_FROM_KEYED);
-}


 static void ReplaceSlowProperty(Handle<JSObject> object,
@@ -2972,29 +2937,28 @@
 }


-MaybeHandle<Object> JSObject::SetPropertyWithInterceptor(
-    Handle<JSObject> object,
-    Handle<Name> name,
-    Handle<Object> value,
-    StrictMode strict_mode) {
+MaybeHandle<Object> JSObject::SetPropertyWithInterceptor(LookupIterator* it, + Handle<Object> value) {
   // TODO(rossberg): Support symbols in the API.
-  if (name->IsSymbol()) return value;
-  Isolate* isolate = object->GetIsolate();
-  Handle<String> name_string = Handle<String>::cast(name);
-  Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
-  if (!interceptor->setter()->IsUndefined()) {
-    LOG(isolate,
-        ApiNamedPropertyAccess("interceptor-named-set", *object, *name));
-    PropertyCallbackArguments args(
-        isolate, interceptor->data(), *object, *object);
-    v8::NamedPropertySetterCallback setter =
- v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter());
-    v8::Handle<v8::Value> result = args.Call(
- setter, v8::Utils::ToLocal(name_string), v8::Utils::ToLocal(value));
-    RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
-    if (!result.IsEmpty()) return value;
-  }
-  return SetPropertyPostInterceptor(object, name, value, strict_mode);
+  if (it->name()->IsSymbol()) return value;
+
+  Handle<String> name_string = Handle<String>::cast(it->name());
+  Handle<JSObject> holder = it->GetHolder();
+  Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor());
+  if (interceptor->setter()->IsUndefined()) return MaybeHandle<Object>();
+
+  LOG(it->isolate(),
+ ApiNamedPropertyAccess("interceptor-named-set", *holder, *name_string)); + PropertyCallbackArguments args(it->isolate(), interceptor->data(), *holder,
+                                 *holder);
+  v8::NamedPropertySetterCallback setter =
+      v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter());
+  v8::Handle<v8::Value> result = args.Call(
+      setter, v8::Utils::ToLocal(name_string), v8::Utils::ToLocal(value));
+  RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
+  if (!result.IsEmpty()) return value;
+
+  return MaybeHandle<Object>();
 }


@@ -3003,12 +2967,194 @@
                                             Handle<Object> value,
                                             StrictMode strict_mode,
                                             StoreFromKeyed store_mode) {
-  LookupResult result(object->GetIsolate());
-  object->LookupOwn(name, &result, true);
-  if (!result.IsFound()) {
- object->map()->LookupTransition(JSObject::cast(*object), *name, &result);
+  LookupIterator it(object, name);
+  return Object::SetProperty(&it, value, strict_mode, store_mode);
+}
+
+
+MaybeHandle<Object> Object::SetProperty(LookupIterator* it,
+                                        Handle<Object> value,
+                                        StrictMode strict_mode,
+                                        StoreFromKeyed store_mode) {
+  // Make sure that the top context does not change when doing callbacks or
+  // interceptor calls.
+  AssertNoContextChange ncc(it->isolate());
+
+  bool done = false;
+  for (; it->IsFound(); it->Next()) {
+    switch (it->state()) {
+      case LookupIterator::NOT_FOUND:
+        UNREACHABLE();
+
+      case LookupIterator::ACCESS_CHECK:
+ // TODO(verwaest): Remove the distinction. This is mostly bogus since we + // don't know whether we'll want to fetch attributes or call a setter
+        // until we find the property.
+        if (it->HasAccess(v8::ACCESS_SET)) break;
+        return JSObject::SetPropertyWithFailedAccessCheck(it, value,
+                                                          strict_mode);
+
+      case LookupIterator::JSPROXY:
+        if (it->HolderIsReceiver()) {
+          return JSProxy::SetPropertyWithHandler(it->GetJSProxy(),
+ it->GetReceiver(), it->name(),
+                                                 value, strict_mode);
+        } else {
+          // TODO(verwaest): Use the MaybeHandle to indicate result.
+          bool has_result = false;
+          MaybeHandle<Object> maybe_result =
+              JSProxy::SetPropertyViaPrototypesWithHandler(
+                  it->GetJSProxy(), it->GetReceiver(), it->name(), value,
+                  strict_mode, &has_result);
+          if (has_result) return maybe_result;
+          done = true;
+        }
+        break;
+
+      case LookupIterator::INTERCEPTOR:
+        if (it->HolderIsReceiver()) {
+          MaybeHandle<Object> maybe_result =
+              JSObject::SetPropertyWithInterceptor(it, value);
+          if (!maybe_result.is_null()) return maybe_result;
+          if (it->isolate()->has_pending_exception()) return maybe_result;
+        } else {
+          Maybe<PropertyAttributes> maybe_attributes =
+              JSObject::GetPropertyAttributesWithInterceptor(
+                  it->GetHolder(), it->GetReceiver(), it->name());
+          RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
+          done = maybe_attributes.has_value;
+          if (done && (maybe_attributes.value & READ_ONLY) != 0) {
+            return WriteToReadOnlyProperty(it, value, strict_mode);
+          }
+        }
+        break;
+
+      case LookupIterator::PROPERTY:
+        if (!it->HasProperty()) break;
+        if (it->property_details().IsReadOnly()) {
+          return WriteToReadOnlyProperty(it, value, strict_mode);
+        }
+        switch (it->property_kind()) {
+          case LookupIterator::ACCESSOR:
+            if (it->HolderIsReceiver() ||
+                !it->GetAccessors()->IsDeclaredAccessorInfo()) {
+              return SetPropertyWithAccessor(it->GetReceiver(), it->name(),
+                                             value, it->GetHolder(),
+ it->GetAccessors(), strict_mode);
+            }
+            break;
+          case LookupIterator::DATA:
+            if (it->HolderIsReceiver()) return SetDataProperty(it, value);
+        }
+        done = true;
+        break;
+    }
+
+    if (done) break;
   }
- return SetProperty(object, &result, name, value, strict_mode, store_mode);
+
+  return AddDataProperty(it, value, NONE, strict_mode, store_mode);
+}
+
+
+MaybeHandle<Object> Object::WriteToReadOnlyProperty(LookupIterator* it,
+                                                    Handle<Object> value,
+ StrictMode strict_mode) {
+  if (strict_mode != STRICT) return value;
+
+  Handle<Object> args[] = {it->name(), it->GetReceiver()};
+  Handle<Object> error = it->factory()->NewTypeError(
+      "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
+  return it->isolate()->Throw<Object>(error);
+}
+
+
+MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it,
+                                            Handle<Object> value) {
+ // Proxies are handled on the WithHandler path. Other non-JSObjects cannot
+  // have own properties.
+  Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
+
+  // Store on the holder which may be hidden behind the receiver.
+  ASSERT(it->HolderIsReceiver());
+
+  // Old value for the observation change record.
+  // Fetch before transforming the object since the encoding may become
+  // incompatible with what's cached in |it|.
+  bool is_observed =
+      receiver->map()->is_observed() &&
+      !it->name().is_identical_to(it->factory()->hidden_string());
+  MaybeHandle<Object> maybe_old;
+  if (is_observed) maybe_old = it->GetDataValue();
+
+  // Possibly migrate to the most up-to-date map that will be able to store
+  // |value| under it->name().
+  it->PrepareForDataProperty(value);
+
+  // Write the property value.
+  it->WriteDataValue(value);
+
+  // Send the change record if there are observers.
+  if (is_observed && !value->SameValue(*maybe_old.ToHandleChecked())) {
+    JSObject::EnqueueChangeRecord(receiver, "update", it->name(),
+                                  maybe_old.ToHandleChecked());
+  }
+
+  return value;
+}
+
+
+MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
+                                            Handle<Object> value,
+                                            PropertyAttributes attributes,
+                                            StrictMode strict_mode,
+                                            StoreFromKeyed store_mode) {
+  ASSERT(!it->GetReceiver()->IsJSProxy());
+  // Transitions to data properties of value wrappers are not observable.
+  if (!it->GetReceiver()->IsJSObject()) return value;
+  Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
+
+ // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject)
+  // instead. If the prototype is Null, the proxy is detached.
+  if (receiver->IsJSGlobalProxy()) {
+    // Trying to assign to a detached proxy.
+    PrototypeIterator iter(it->isolate(), receiver);
+    if (iter.IsAtEnd()) return value;
+    receiver =
+        Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter));
+  }
+
+  if (!receiver->map()->is_extensible()) {
+    if (strict_mode == SLOPPY) return value;
+
+    Handle<Object> args[1] = {it->name()};
+    Handle<Object> error = it->factory()->NewTypeError(
+        "object_not_extensible", HandleVector(args, ARRAY_SIZE(args)));
+    return it->isolate()->Throw<Object>(error);
+  }
+
+  // Possibly migrate to the most up-to-date map that will be able to store
+  // |value| under it->name() with |attributes|.
+  it->TransitionToDataProperty(value, attributes, store_mode);
+
+  // TODO(verwaest): Encapsulate dictionary handling better.
+  if (receiver->map()->is_dictionary_map()) {
+    // TODO(verwaest): Probably should ensure this is done beforehand.
+    it->InternalizeName();
+    JSObject::AddSlowProperty(receiver, it->name(), value, attributes);
+  } else {
+    // Write the property value.
+    it->WriteDataValue(value);
+  }
+
+  // Send the change record if there are observers.
+  if (receiver->map()->is_observed() &&
+      !it->name().is_identical_to(it->factory()->hidden_string())) {
+    JSObject::EnqueueChangeRecord(receiver, "add", it->name(),
+                                  it->factory()->the_hole_value());
+  }
+
+  return value;
 }


@@ -3047,66 +3193,6 @@
   *found = false;
   return isolate->factory()->the_hole_value();
 }
-
-
-MaybeHandle<Object> JSObject::SetPropertyViaPrototypes(
-    Handle<JSObject> object,
-    Handle<Name> name,
-    Handle<Object> value,
-    StrictMode strict_mode,
-    bool* done) {
-  Isolate* isolate = object->GetIsolate();
-
-  *done = false;
-  // We could not find an own property, so let's check whether there is an
-  // accessor that wants to handle the property, or whether the property is
-  // read-only on the prototype chain.
-  LookupResult result(isolate);
-  object->LookupRealNamedPropertyInPrototypes(name, &result);
-  if (result.IsFound()) {
-    switch (result.type()) {
-      case NORMAL:
-      case FIELD:
-      case CONSTANT:
-        *done = result.IsReadOnly();
-        break;
-      case INTERCEPTOR: {
-        LookupIterator it(object, name, handle(result.holder()));
-        PropertyAttributes attr = GetPropertyAttributes(&it);
-        *done = !!(attr & READ_ONLY);
-        break;
-      }
-      case CALLBACKS: {
-        *done = true;
-        if (!result.IsReadOnly()) {
- Handle<Object> callback_object(result.GetCallbackObject(), isolate);
-          return SetPropertyWithCallback(object, name, value,
-                                         handle(result.holder()),
-                                         callback_object, strict_mode);
-        }
-        break;
-      }
-      case HANDLER: {
-        Handle<JSProxy> proxy(result.proxy());
-        return JSProxy::SetPropertyViaPrototypesWithHandler(
-            proxy, object, name, value, strict_mode, done);
-      }
-      case NONEXISTENT:
-        UNREACHABLE();
-        break;
-    }
-  }
-
- // If we get here with *done true, we have encountered a read-only property.
-  if (*done) {
-    if (strict_mode == SLOPPY) return value;
-    Handle<Object> args[] = { name, object };
-    Handle<Object> error = isolate->factory()->NewTypeError(
-        "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
-    return isolate->Throw<Object>(error);
-  }
-  return isolate->factory()->the_hole_value();
-}


 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) {
@@ -3506,23 +3592,6 @@
   }
   result->NotFound();
 }
-
-
-MaybeHandle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
-                                            LookupResult* result,
-                                            Handle<Name> key,
-                                            Handle<Object> value,
-                                            StrictMode strict_mode,
-                                            StoreFromKeyed store_mode) {
-  if (result->IsHandler()) {
- return JSProxy::SetPropertyWithHandler(handle(result->proxy()), object, key,
-                                           value, strict_mode);
-  } else {
-    return JSObject::SetPropertyForResult(Handle<JSObject>::cast(object),
-                                          result, key, value, strict_mode,
-                                          store_mode);
-  }
-}


bool JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name) {
@@ -3546,12 +3615,11 @@
 }


-MaybeHandle<Object> JSProxy::SetPropertyWithHandler(
-    Handle<JSProxy> proxy,
-    Handle<JSReceiver> receiver,
-    Handle<Name> name,
-    Handle<Object> value,
-    StrictMode strict_mode) {
+MaybeHandle<Object> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy,
+ Handle<Object> receiver,
+                                                    Handle<Name> name,
+                                                    Handle<Object> value,
+ StrictMode strict_mode) {
   Isolate* isolate = proxy->GetIsolate();

   // TODO(rossberg): adjust once there is a story for symbols vs proxies.
@@ -3572,12 +3640,8 @@


 MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
-    Handle<JSProxy> proxy,
-    Handle<JSReceiver> receiver,
-    Handle<Name> name,
-    Handle<Object> value,
-    StrictMode strict_mode,
-    bool* done) {
+    Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name,
+    Handle<Object> value, StrictMode strict_mode, bool* done) {
   Isolate* isolate = proxy->GetIsolate();
Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy.

@@ -3996,7 +4060,7 @@
                                         Handle<Object> value,
                                         PropertyAttributes attributes) {
   Handle<JSObject> object(lookup->holder());
-  if (object->TooManyFastProperties()) {
+ if (object->map()->TooManyFastProperties(Object::MAY_BE_STORE_FROM_KEYED)) {
     JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
   }

@@ -4032,140 +4096,6 @@
     ConvertAndSetOwnProperty(lookup, name, value, attributes);
   }
 }
-
-
-MaybeHandle<Object> JSObject::SetPropertyForResult(
-    Handle<JSObject> object,
-    LookupResult* lookup,
-    Handle<Name> name,
-    Handle<Object> value,
-    StrictMode strict_mode,
-    StoreFromKeyed store_mode) {
-  ASSERT(!value->IsTheHole());
-  Isolate* isolate = object->GetIsolate();
-
-  // Make sure that the top context does not change when doing callbacks or
-  // interceptor calls.
-  AssertNoContextChange ncc(isolate);
-
-  // Optimization for 2-byte strings often used as keys in a decompression
-  // dictionary.  We internalize these short keys to avoid constantly
-  // reallocating them.
-  if (name->IsString() && !name->IsInternalizedString() &&
-      Handle<String>::cast(name)->length() <= 2) {
- name = isolate->factory()->InternalizeString(Handle<String>::cast(name));
-  }
-
-  // Check access rights if needed.
-  if (object->IsAccessCheckNeeded()) {
-    if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) {
-      return SetPropertyWithFailedAccessCheck(object, lookup, name, value,
-                                              true, strict_mode);
-    }
-  }
-
-  if (object->IsJSGlobalProxy()) {
-    PrototypeIterator iter(isolate, object);
-    if (iter.IsAtEnd()) return value;
-    ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
-    return SetPropertyForResult(
- Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), lookup,
-        name, value, strict_mode, store_mode);
-  }
-
-  ASSERT(!lookup->IsFound() || lookup->holder() == *object ||
-         lookup->holder()->map()->is_hidden_prototype());
-
-  if (!lookup->IsProperty() && !object->IsJSContextExtensionObject()) {
-    bool done = false;
-    Handle<Object> result_object;
-    ASSIGN_RETURN_ON_EXCEPTION(
-        isolate, result_object,
-        SetPropertyViaPrototypes(object, name, value, strict_mode, &done),
-        Object);
-    if (done) return result_object;
-  }
-
-  if (!lookup->IsFound()) {
-    // Neither properties nor transitions found.
-    return AddPropertyInternal(object, name, value, NONE, strict_mode,
-                               store_mode);
-  }
-
-  if (lookup->IsProperty() && lookup->IsReadOnly()) {
-    if (strict_mode == STRICT) {
-      Handle<Object> args[] = { name, object };
-      Handle<Object> error = isolate->factory()->NewTypeError(
- "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
-      return isolate->Throw<Object>(error);
-    } else {
-      return value;
-    }
-  }
-
-  Handle<Object> old_value = isolate->factory()->the_hole_value();
-  bool is_observed = object->map()->is_observed() &&
-                     *name != isolate->heap()->hidden_string();
-  if (is_observed && lookup->IsDataProperty()) {
- old_value = Object::GetPropertyOrElement(object, name).ToHandleChecked();
-  }
-
-  // This is a real property that is not read-only, or it is a
- // transition or null descriptor and there are no setters in the prototypes.
-  MaybeHandle<Object> maybe_result = value;
-  if (lookup->IsTransition()) {
- maybe_result = SetPropertyUsingTransition(handle(lookup->holder()), lookup,
-                                              name, value, NONE);
-  } else {
-    switch (lookup->type()) {
-      case NORMAL:
-        SetNormalizedProperty(handle(lookup->holder()), lookup, value);
-        break;
-      case FIELD:
-        SetPropertyToField(lookup, value);
-        break;
-      case CONSTANT:
-        // Only replace the constant if necessary.
-        if (*value == lookup->GetConstant()) return value;
-        SetPropertyToField(lookup, value);
-        break;
-      case CALLBACKS: {
- Handle<Object> callback_object(lookup->GetCallbackObject(), isolate);
-        return SetPropertyWithCallback(object, name, value,
-                                       handle(lookup->holder()),
-                                       callback_object, strict_mode);
-      }
-      case INTERCEPTOR:
-        maybe_result = SetPropertyWithInterceptor(handle(lookup->holder()),
- name, value, strict_mode);
-        break;
-      case HANDLER:
-      case NONEXISTENT:
-        UNREACHABLE();
-    }
-  }
-
-  Handle<Object> result;
-  ASSIGN_RETURN_ON_EXCEPTION(isolate, result, maybe_result, Object);
-
-  if (is_observed) {
-    if (lookup->IsTransition()) {
-      EnqueueChangeRecord(object, "add", name, old_value);
-    } else {
-      LookupResult new_lookup(isolate);
-      object->LookupOwn(name, &new_lookup, true);
-      if (new_lookup.IsDataProperty()) {
-        Handle<Object> new_value =
-            Object::GetPropertyOrElement(object, name).ToHandleChecked();
-        if (!new_value->SameValue(*old_value)) {
-          EnqueueChangeRecord(object, "update", name, old_value);
-        }
-      }
-    }
-  }
-
-  return result;
-}


 void JSObject::AddProperty(
@@ -4215,8 +4145,8 @@
   // Check access rights if needed.
   if (object->IsAccessCheckNeeded()) {
     if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) {
-      return SetPropertyWithFailedAccessCheck(object, &lookup, name, value,
-                                              false, SLOPPY);
+      LookupIterator it(object, name, LookupIterator::CHECK_OWN);
+      return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY);
     }
   }

@@ -4288,13 +4218,9 @@
             handling == DONT_FORCE_FIELD) {
           Handle<Object> result;
           ASSIGN_RETURN_ON_EXCEPTION(
-              isolate, result,
-              JSObject::SetPropertyWithCallback(object,
-                                                name,
-                                                value,
-                                                handle(lookup.holder()),
-                                                callback,
-                                                STRICT),
+              isolate, result, JSObject::SetPropertyWithAccessor(
+ object, name, value, handle(lookup.holder()),
+                                   callback, STRICT),
               Object);

           if (attributes != lookup.GetAttributes()) {
@@ -4363,7 +4289,7 @@
     Handle<Object> receiver,
     Handle<Name> name) {
   // TODO(rossberg): Support symbols in the API.
-  if (name->IsSymbol()) return Maybe<PropertyAttributes>(ABSENT);
+  if (name->IsSymbol()) return Maybe<PropertyAttributes>();

   Isolate* isolate = holder->GetIsolate();
   HandleScope scope(isolate);
@@ -7365,6 +7291,97 @@
   new_map->set_elements_kind(DICTIONARY_ELEMENTS);
   return new_map;
 }
+
+
+bool DescriptorArray::CanHoldValue(int descriptor, Object* value) {
+  PropertyDetails details = GetDetails(descriptor);
+  switch (details.type()) {
+    case FIELD:
+      return value->FitsRepresentation(details.representation()) &&
+             GetFieldType(descriptor)->NowContains(value);
+
+    case CONSTANT:
+      ASSERT(GetConstant(descriptor) != value ||
+             value->FitsRepresentation(details.representation()));
+      return GetConstant(descriptor) == value;
+
+    case CALLBACKS:
+      return false;
+
+    case NORMAL:
+    case INTERCEPTOR:
+    case HANDLER:
+    case NONEXISTENT:
+      break;
+  }
+
+  UNREACHABLE();
+  return false;
+}
+
+
+Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor,
+                                        Handle<Object> value) {
+  // Dictionaries can store any property value.
+  if (map->is_dictionary_map()) return map;
+
+  Handle<DescriptorArray> descriptors(map->instance_descriptors());
+
+  if (descriptors->CanHoldValue(descriptor, *value)) return map;
+
+  Isolate* isolate = map->GetIsolate();
+  Representation representation = value->OptimalRepresentation();
+  Handle<HeapType> type = value->OptimalType(isolate, representation);
+
+  return GeneralizeRepresentation(map, descriptor, representation, type,
+                                  FORCE_FIELD);
+}
+
+
+Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name,
+                                          Handle<Object> value,
+                                          PropertyAttributes attributes,
+                                          StoreFromKeyed store_mode) {
+  // Cannot currently handle deprecated maps.
+  ASSERT(!map->is_deprecated());
+  // Dictionary maps can always have additional data properties.
+  if (map->is_dictionary_map()) return map;
+
+  int index = map->SearchTransition(*name);
+  if (index != TransitionArray::kNotFound) {
+    Handle<Map> transition(map->GetTransition(index));
+    int descriptor = transition->LastAdded();
+
+    // TODO(verwaest): Handle attributes better.
+    DescriptorArray* descriptors = transition->instance_descriptors();
+    if (descriptors->GetDetails(descriptor).attributes() != attributes) {
+      return CopyGeneralizeAllRepresentations(transition, descriptor,
+                                              FORCE_FIELD, attributes,
+                                              "attributes mismatch");
+    }
+
+    return Map::PrepareForDataProperty(transition, descriptor, value);
+  }
+
+  TransitionFlag flag = INSERT_TRANSITION;
+  MaybeHandle<Map> maybe_map;
+  if (value->IsJSFunction()) {
+    maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag);
+  } else if (!map->TooManyFastProperties(store_mode)) {
+    Isolate* isolate = name->GetIsolate();
+    Representation representation = value->OptimalRepresentation();
+    Handle<HeapType> type = value->OptimalType(isolate, representation);
+    maybe_map =
+ Map::CopyWithField(map, name, type, attributes, representation, flag);
+  }
+
+  Handle<Map> result;
+  if (!maybe_map.ToHandle(&result)) {
+    return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES);
+  }
+
+  return result;
+}


 Handle<Map> Map::CopyAddDescriptor(Handle<Map> map,
=======================================
--- /branches/bleeding_edge/src/objects.h       Thu Jul 17 09:44:37 2014 UTC
+++ /branches/bleeding_edge/src/objects.h       Fri Jul 18 13:47:25 2014 UTC
@@ -1375,6 +1375,13 @@
   HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
 #undef IS_TYPE_FUNCTION_DECL

+  // A non-keyed store is of the form a.x = foo or a["x"] = foo whereas
+  // a keyed store is of the form a[expression] = foo.
+  enum StoreFromKeyed {
+    MAY_BE_STORE_FROM_KEYED,
+    CERTAINLY_NOT_STORE_FROM_KEYED
+  };
+
   INLINE(bool IsFixedArrayBase() const);
   INLINE(bool IsExternal() const);
   INLINE(bool IsAccessorInfo() const);
@@ -1476,6 +1483,16 @@
   void Lookup(Handle<Name> name, LookupResult* result);

MUST_USE_RESULT static MaybeHandle<Object> GetProperty(LookupIterator* it);
+  MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
+      LookupIterator* it, Handle<Object> value, StrictMode strict_mode,
+      StoreFromKeyed store_mode);
+  MUST_USE_RESULT static MaybeHandle<Object> WriteToReadOnlyProperty(
+      LookupIterator* it, Handle<Object> value, StrictMode strict_mode);
+  MUST_USE_RESULT static MaybeHandle<Object> SetDataProperty(
+      LookupIterator* it, Handle<Object> value);
+  MUST_USE_RESULT static MaybeHandle<Object> AddDataProperty(
+ LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
+      StrictMode strict_mode, StoreFromKeyed store_mode);
   MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
       Handle<Object> object,
       Handle<Name> key);
@@ -1492,12 +1509,9 @@
       Handle<Name> name,
       Handle<JSObject> holder,
       Handle<Object> structure);
-  MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithCallback(
-      Handle<Object> receiver,
-      Handle<Name> name,
-      Handle<Object> value,
-      Handle<JSObject> holder,
-      Handle<Object> structure,
+  MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithAccessor(
+      Handle<Object> receiver, Handle<Name> name, Handle<Object> value,
+      Handle<JSObject> holder, Handle<Object> structure,
       StrictMode strict_mode);

   MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithDefinedGetter(
@@ -1918,13 +1932,6 @@
     FORCE_DELETION
   };

-  // A non-keyed store is of the form a.x = foo or a["x"] = foo whereas
-  // a keyed store is of the form a[expression] = foo.
-  enum StoreFromKeyed {
-    MAY_BE_STORE_FROM_KEYED,
-    CERTAINLY_NOT_STORE_FROM_KEYED
-  };
-
   // Internal properties (e.g. the hidden properties dictionary) might
   // be added even though the receiver is non-extensible.
   enum ExtensibilityCheck {
@@ -2136,18 +2143,7 @@
                                                    uint32_t limit);

   MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithInterceptor(
-      Handle<JSObject> object,
-      Handle<Name> name,
-      Handle<Object> value,
-      StrictMode strict_mode);
-
-  MUST_USE_RESULT static MaybeHandle<Object> SetPropertyForResult(
-      Handle<JSObject> object,
-      LookupResult* result,
-      Handle<Name> name,
-      Handle<Object> value,
-      StrictMode strict_mode,
-      StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
+      LookupIterator* it, Handle<Object> value);

// SetLocalPropertyIgnoreAttributes converts callbacks to fields. We need to
   // grant an exemption to ExecutableAccessor callbacks in some cases.
@@ -2573,12 +2569,6 @@

   Object* SlowReverseLookup(Object* value);

-  // Maximal number of fast properties for the JSObject. Used to
-  // restrict the number of map transitions to avoid an explosion in
-  // the number of maps for objects used as dictionaries.
-  inline bool TooManyFastProperties(
-      StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
-
   // Maximal number of elements (numbered 0 .. kMaxElementCount - 1).
   // Also maximal value of JSArray's length property.
   static const uint32_t kMaxElementCount = 0xffffffffu;
@@ -2606,8 +2596,6 @@
   // "global.Object" and not to arbitrary other JSObject maps.
   static const int kInitialGlobalObjectUnusedPropertiesCount = 4;

-  static const int kFastPropertiesSoftLimit = 12;
-  static const int kMaxFastProperties = 128;
   static const int kMaxInstanceSize = 255 * kPointerSize;
   // When extending the backing storage for property values, we increase
// its size by more than the 1 entry necessary, so sequentially adding fields
@@ -2734,21 +2722,6 @@
       StrictMode strict_mode,
       bool check_prototype = true);

-  // Searches the prototype chain for property 'name'. If it is found and
-  // has a setter, invoke it and set '*done' to true. If it is found and is
-  // read-only, reject and set '*done' to true. Otherwise, set '*done' to
-  // false. Can throw and return an empty handle with '*done==true'.
-  MUST_USE_RESULT static MaybeHandle<Object> SetPropertyViaPrototypes(
-      Handle<JSObject> object,
-      Handle<Name> name,
-      Handle<Object> value,
-      StrictMode strict_mode,
-      bool* done);
-  MUST_USE_RESULT static MaybeHandle<Object> SetPropertyPostInterceptor(
-      Handle<JSObject> object,
-      Handle<Name> name,
-      Handle<Object> value,
-      StrictMode strict_mode);
   MUST_USE_RESULT static MaybeHandle<Object> SetPropertyUsingTransition(
       Handle<JSObject> object,
       LookupResult* lookup,
@@ -2756,12 +2729,7 @@
       Handle<Object> value,
       PropertyAttributes attributes);
MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithFailedAccessCheck(
-      Handle<JSObject> object,
-      LookupResult* result,
-      Handle<Name> name,
-      Handle<Object> value,
-      bool check_prototype,
-      StrictMode strict_mode);
+      LookupIterator* it, Handle<Object> value, StrictMode strict_mode);

   // Add a property to an object.
   MUST_USE_RESULT static MaybeHandle<Object> AddPropertyInternal(
@@ -3452,6 +3420,8 @@
                     FixedArray* new_cache,
                     Object* new_index_cache);

+  bool CanHoldValue(int descriptor, Object* value);
+
   // Accessors for fetching instance descriptor at descriptor number.
   inline Name* GetKey(int descriptor_number);
   inline Object** GetKeySlot(int descriptor_number);
@@ -6334,6 +6304,10 @@
       StoreMode store_mode,
       const char* reason);

+  static Handle<Map> PrepareForDataProperty(Handle<Map> old_map,
+                                            int descriptor_number,
+                                            Handle<Object> value);
+
static Handle<Map> Normalize(Handle<Map> map, PropertyNormalizationMode mode);

// Returns the constructor name (the name (possibly, inferred name) of the
@@ -6526,6 +6500,15 @@
   static Handle<Map> CopyForObserved(Handle<Map> map);

   static Handle<Map> CopyForFreeze(Handle<Map> map);
+  // Maximal number of fast properties. Used to restrict the number of map
+ // transitions to avoid an explosion in the number of maps for objects used as
+  // dictionaries.
+  inline bool TooManyFastProperties(StoreFromKeyed store_mode);
+  static Handle<Map> TransitionToDataProperty(Handle<Map> map,
+                                              Handle<Name> name,
+                                              Handle<Object> value,
+ PropertyAttributes attributes,
+                                              StoreFromKeyed store_mode);

   inline void AppendDescriptor(Descriptor* desc);

@@ -6834,6 +6817,9 @@
                                             Handle<Object> prototype,
                                             Handle<Map> target_map);

+  static const int kFastPropertiesSoftLimit = 12;
+  static const int kMaxFastProperties = 128;
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(Map);
 };

@@ -9968,12 +9954,8 @@
   // otherwise set it to false.
   MUST_USE_RESULT
   static MaybeHandle<Object> SetPropertyViaPrototypesWithHandler(
-      Handle<JSProxy> proxy,
-      Handle<JSReceiver> receiver,
-      Handle<Name> name,
-      Handle<Object> value,
-      StrictMode strict_mode,
-      bool* done);
+      Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name,
+      Handle<Object> value, StrictMode strict_mode, bool* done);

   static PropertyAttributes GetPropertyAttributesWithHandler(
       Handle<JSProxy> proxy,
@@ -9983,6 +9965,9 @@
       Handle<JSProxy> proxy,
       Handle<JSReceiver> receiver,
       uint32_t index);
+  MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithHandler(
+      Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name,
+      Handle<Object> value, StrictMode strict_mode);

   // Turn the proxy into an (empty) JSObject.
   static void Fix(Handle<JSProxy> proxy);
@@ -10022,12 +10007,6 @@
  private:
   friend class JSReceiver;

-  MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithHandler(
-      Handle<JSProxy> proxy,
-      Handle<JSReceiver> receiver,
-      Handle<Name> name,
-      Handle<Object> value,
-      StrictMode strict_mode);
   MUST_USE_RESULT static inline MaybeHandle<Object> SetElementWithHandler(
       Handle<JSProxy> proxy,
       Handle<JSReceiver> receiver,
=======================================
--- /branches/bleeding_edge/src/stub-cache.cc   Thu Jul 17 09:44:37 2014 UTC
+++ /branches/bleeding_edge/src/stub-cache.cc   Fri Jul 18 13:47:25 2014 UTC
@@ -581,8 +581,8 @@
   ASSERT(receiver->HasNamedInterceptor());
   Handle<Object> result;
   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, JSObject::SetPropertyWithInterceptor(
-                           receiver, name, value, ic.strict_mode()));
+      isolate, result,
+      JSObject::SetProperty(receiver, name, value, ic.strict_mode()));
   return *result;
 }

=======================================
--- /branches/bleeding_edge/src/v8natives.js    Mon Jul 14 14:05:30 2014 UTC
+++ /branches/bleeding_edge/src/v8natives.js    Fri Jul 18 13:47:25 2014 UTC
@@ -1322,7 +1322,9 @@
   for (var i = 0; i < names.length; i++) {
     var name = names[i];
     var desc = GetOwnPropertyJS(obj, name);
-    if (desc.isConfigurable()) return false;
+    if (desc.isConfigurable()) {
+      return false;
+    }
   }
   return true;
 }
=======================================
--- /branches/bleeding_edge/test/cctest/test-decls.cc Mon Jul 14 14:01:04 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-decls.cc Fri Jul 18 13:47:25 2014 UTC
@@ -423,11 +423,8 @@
   // Sanity check to make sure that the holder of the interceptor
   // really is the prototype object.
   { ExistsInPrototypeContext context;
-    context.Check("this.x = 87; this.x",
-                  0,
-                  0,
-                  0,
-                  EXPECT_RESULT, Number::New(CcTest::isolate(), 87));
+    context.Check("this.x = 87; this.x", 0, 0, 1, EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 87));
   }

   { ExistsInPrototypeContext context;

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to