Replace SetObjectProperty / DefineObjectProperty with less powerful alternatives...
authorverwaest <verwaest@chromium.org>
Thu, 11 Jun 2015 16:37:35 +0000 (09:37 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 11 Jun 2015 16:37:48 +0000 (16:37 +0000)
@yangguo: please look at the debugger part of the CL.
@ishell: please look at the rest.

Additionally:
- Ensure the LookupIterator for named properties does not accidentally get indexes in.
- Fix the return value for typed array assignments to be the incoming value.

BUG=v8:4137
LOG=n

Review URL: https://codereview.chromium.org/1178503004

Cr-Commit-Position: refs/heads/master@{#28954}

16 files changed:
src/api-natives.cc
src/api.cc
src/bootstrapper.cc
src/ic/ic.cc
src/json-parser.h
src/lookup.cc
src/lookup.h
src/objects-inl.h
src/objects.cc
src/objects.h
src/runtime/runtime-classes.cc
src/runtime/runtime-debug.cc
src/runtime/runtime-object.cc
src/runtime/runtime.h
src/scopeinfo.cc
test/cctest/test-debug.cc

index 71a039f35ea8d4d312e43a398392630190618163..74518447ea329a61a703cd66fa459d5ca2b1ee4f 100644 (file)
@@ -80,32 +80,24 @@ MaybeHandle<Object> DefineDataProperty(Isolate* isolate,
   ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
                              Instantiate(isolate, prop_data, key), Object);
 
+  uint32_t index = 0;
+  LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
+  LookupIterator it = key->AsArrayIndex(&index)
+                          ? LookupIterator(isolate, object, index, c)
+                          : LookupIterator(object, key, c);
+
 #ifdef DEBUG
-  bool duplicate;
-  if (key->IsName()) {
-    LookupIterator it(object, Handle<Name>::cast(key),
-                      LookupIterator::OWN_SKIP_INTERCEPTOR);
-    Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
-    DCHECK(maybe.IsJust());
-    duplicate = it.IsFound();
-  } else {
-    uint32_t index = 0;
-    key->ToArrayIndex(&index);
-    Maybe<bool> maybe = JSReceiver::HasOwnElement(object, index);
-    if (!maybe.IsJust()) return MaybeHandle<Object>();
-    duplicate = maybe.FromJust();
-  }
-  if (duplicate) {
+  Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
+  DCHECK(maybe.IsJust());
+  if (it.IsFound()) {
     THROW_NEW_ERROR(
         isolate, NewTypeError(MessageTemplate::kDuplicateTemplateProperty, key),
         Object);
   }
 #endif
 
-  RETURN_ON_EXCEPTION(
-      isolate, Runtime::DefineObjectProperty(object, key, value, attributes),
-      Object);
-  return object;
+  return Object::AddDataProperty(&it, value, attributes, STRICT,
+                                 Object::CERTAINLY_NOT_STORE_FROM_KEYED);
 }
 
 
index b8812800081d1b36ea84b5871c2a80a8d870bb93..0bd435b738b64bb11e3d6a586e7a2217f04fdbdf 100644 (file)
@@ -3535,7 +3535,7 @@ Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
 
   if (it.IsFound() && !it.IsConfigurable()) return Just(false);
 
-  has_pending_exception = i::Runtime::DefineObjectProperty(
+  has_pending_exception = i::JSObject::SetOwnPropertyIgnoreAttributes(
                               self, key_obj, value_obj, NONE).is_null();
   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
   return Just(true);
@@ -3573,9 +3573,8 @@ Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
     return Just(false);
   }
 
-  has_pending_exception = i::Runtime::DefineObjectProperty(
-                              self, isolate->factory()->Uint32ToString(index),
-                              value_obj, NONE).is_null();
+  has_pending_exception = i::JSObject::SetOwnElementIgnoreAttributes(
+                              self, index, value_obj, NONE).is_null();
   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
   return Just(true);
 }
@@ -3613,6 +3612,34 @@ Maybe<bool> v8::Object::DefineOwnProperty(v8::Local<v8::Context> context,
 }
 
 
+MUST_USE_RESULT
+static i::MaybeHandle<i::Object> DefineObjectProperty(
+    i::Handle<i::JSObject> js_object, i::Handle<i::Object> key,
+    i::Handle<i::Object> value, PropertyAttributes attrs) {
+  i::Isolate* isolate = js_object->GetIsolate();
+  // Check if the given key is an array index.
+  uint32_t index = 0;
+  if (key->ToArrayIndex(&index)) {
+    return i::JSObject::SetOwnElementIgnoreAttributes(js_object, index, value,
+                                                      attrs);
+  }
+
+  i::Handle<i::Name> name;
+  if (key->IsName()) {
+    name = i::Handle<i::Name>::cast(key);
+  } else {
+    // Call-back into JavaScript to convert the key to a string.
+    i::Handle<i::Object> converted;
+    ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, converted,
+                                     i::Execution::ToString(isolate, key),
+                                     i::MaybeHandle<i::Object>());
+    name = i::Handle<i::String>::cast(converted);
+  }
+
+  return i::JSObject::DefinePropertyOrElement(js_object, name, value, attrs);
+}
+
+
 Maybe<bool> v8::Object::ForceSet(v8::Local<v8::Context> context,
                                  v8::Local<Value> key, v8::Local<Value> value,
                                  v8::PropertyAttribute attribs) {
@@ -3620,11 +3647,9 @@ Maybe<bool> v8::Object::ForceSet(v8::Local<v8::Context> context,
   auto self = Utils::OpenHandle(this);
   auto key_obj = Utils::OpenHandle(*key);
   auto value_obj = Utils::OpenHandle(*value);
-  has_pending_exception = i::Runtime::DefineObjectProperty(
-      self,
-      key_obj,
-      value_obj,
-      static_cast<PropertyAttributes>(attribs)).is_null();
+  has_pending_exception =
+      DefineObjectProperty(self, key_obj, value_obj,
+                           static_cast<PropertyAttributes>(attribs)).is_null();
   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
   return Just(true);
 }
@@ -3640,9 +3665,8 @@ bool v8::Object::ForceSet(v8::Handle<Value> key, v8::Handle<Value> value,
   i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
   has_pending_exception =
-      i::Runtime::DefineObjectProperty(self, key_obj, value_obj,
-                                       static_cast<PropertyAttributes>(attribs))
-          .is_null();
+      DefineObjectProperty(self, key_obj, value_obj,
+                           static_cast<PropertyAttributes>(attribs)).is_null();
   EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, false);
   return true;
 }
index c675fe7e0d423211669c505a2f1a7a4169a9aa31..f4768de3a9e281efd7ccd73113acdd7184c31954 100644 (file)
@@ -940,8 +940,9 @@ void Genesis::HookUpGlobalObject(Handle<GlobalObject> global_object,
 
   static const PropertyAttributes attributes =
       static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
-  Runtime::DefineObjectProperty(builtins_global, factory()->global_string(),
-                                global_object, attributes).Assert();
+  JSObject::SetOwnPropertyIgnoreAttributes(builtins_global,
+                                           factory()->global_string(),
+                                           global_object, attributes).Assert();
   // Set up the reference from the global object to the builtins object.
   JSGlobalObject::cast(*global_object)->set_builtins(*builtins_global);
   TransferNamedProperties(global_object_from_snapshot, global_object);
index c0d8e005abedeb32ce95b1d70c396e590e24a719..d04fc583c44a909cc0d57c900a7da160c88236aa 100644 (file)
@@ -1226,7 +1226,7 @@ static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) {
     } else {
       int int_value = FastD2I(value);
       if (value == int_value && Smi::IsValid(int_value)) {
-        key = Handle<Smi>(Smi::FromInt(int_value), isolate);
+        key = handle(Smi::FromInt(int_value), isolate);
       }
     }
   } else if (key->IsUndefined()) {
index 9234e85aa20d171fcad6a1f27a5317457debee1b..8ed2e84059cfb7aa9fe74e4ff0b3db16ae71cc45 100644 (file)
@@ -434,7 +434,7 @@ Handle<Object> JsonParser<seq_one_byte>::ParseJsonObject() {
       // Commit the intermediate state to the object and stop transitioning.
       CommitStateToJsonObject(json_object, map, &properties);
 
-      Runtime::DefineObjectProperty(json_object, key, value, NONE).Check();
+      JSObject::DefinePropertyOrElement(json_object, key, value).Check();
     } while (transitioning && MatchSkipWhiteSpace(','));
 
     // If we transitioned until the very end, transition the map now.
@@ -470,7 +470,7 @@ Handle<Object> JsonParser<seq_one_byte>::ParseJsonObject() {
         value = ParseJsonValue();
         if (value.is_null()) return ReportUnexpectedCharacter();
 
-        Runtime::DefineObjectProperty(json_object, key, value, NONE).Check();
+        JSObject::DefinePropertyOrElement(json_object, key, value).Check();
       }
     }
 
index 1bb491a9dee2aa528f1a85de8a9756f99c8143bf..6a26663b44f87380dfaf9efb5ed16b57467e35ca 100644 (file)
@@ -419,12 +419,12 @@ Handle<Object> LookupIterator::GetDataValue() const {
 }
 
 
-Handle<Object> LookupIterator::WriteDataValue(Handle<Object> value) {
+void LookupIterator::WriteDataValue(Handle<Object> value) {
   DCHECK_EQ(DATA, state_);
   Handle<JSObject> holder = GetHolder<JSObject>();
   if (IsElement()) {
     ElementsAccessor* accessor = holder->GetElementsAccessor();
-    return accessor->Set(holder, index_, value);
+    accessor->Set(holder, index_, value);
   } else if (holder->IsGlobalObject()) {
     Handle<GlobalDictionary> property_dictionary =
         handle(holder->global_dictionary());
@@ -439,7 +439,6 @@ Handle<Object> LookupIterator::WriteDataValue(Handle<Object> value) {
   } else {
     DCHECK_EQ(v8::internal::DATA_CONSTANT, property_details_.type());
   }
-  return value;
 }
 
 
index be8394afec4e7242fd294695f6b31f347dac8628..48604b2389a375da7a99dd09bea37e217bfb3062 100644 (file)
@@ -59,12 +59,10 @@ class LookupIterator final BASE_EMBEDDED {
         holder_map_(holder_->map(), isolate_),
         initial_holder_(holder_),
         number_(DescriptorArray::kNotFound) {
-#if 0  // TODO(verwaest): Enable once blocking hacks are removed.
 #ifdef DEBUG
     uint32_t index;  // Assert that the name is not an array index.
     DCHECK(!name->AsArrayIndex(&index));
 #endif  // DEBUG
-#endif
     Next();
   }
 
@@ -85,12 +83,10 @@ class LookupIterator final BASE_EMBEDDED {
         holder_map_(holder_->map(), isolate_),
         initial_holder_(holder_),
         number_(DescriptorArray::kNotFound) {
-#if 0  // TODO(verwaest): Enable once blocking hacks are removed.
 #ifdef DEBUG
     uint32_t index;  // Assert that the name is not an array index.
     DCHECK(!name->AsArrayIndex(&index));
 #endif  // DEBUG
-#endif
     Next();
   }
 
@@ -212,9 +208,7 @@ class LookupIterator final BASE_EMBEDDED {
   Handle<Object> GetAccessors() const;
   Handle<InterceptorInfo> GetInterceptor() const;
   Handle<Object> GetDataValue() const;
-  // Usually returns the value that was passed in. In case of typed array
-  // accesses it returns the converted value.
-  Handle<Object> WriteDataValue(Handle<Object> value);
+  void WriteDataValue(Handle<Object> value);
   void InternalizeName();
 
  private:
index 27528d644253793d8418fc019ec183557cd52c31..501eef4c20086a1d2361542b0117d0eb1a868340 100644 (file)
@@ -1197,6 +1197,20 @@ MaybeHandle<Object> Object::GetProperty(Isolate* isolate,
 }
 
 
+MaybeHandle<Object> JSObject::DefinePropertyOrElement(
+    Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
+    PropertyAttributes attributes) {
+  uint32_t index;
+  if (name->AsArrayIndex(&index)) {
+    return SetOwnElementIgnoreAttributes(object, index, value, attributes);
+  }
+
+  // TODO(verwaest): Is this necessary?
+  if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
+  return SetOwnPropertyIgnoreAttributes(object, name, value, attributes);
+}
+
+
 #define FIELD_ADDR(p, offset) \
   (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
 
index 180255f4fd39cca153b7323c0d1c1f990224322e..7e402184b1f5e1c82cc9fa6719ed363f50393e13 100644 (file)
@@ -3223,17 +3223,6 @@ MaybeHandle<Object> Object::WriteToReadOnlyProperty(
 }
 
 
-MaybeHandle<Object> Object::WriteToReadOnlyElement(Isolate* isolate,
-                                                   Handle<Object> receiver,
-                                                   uint32_t index,
-                                                   Handle<Object> value,
-                                                   LanguageMode language_mode) {
-  return WriteToReadOnlyProperty(isolate, receiver,
-                                 isolate->factory()->NewNumberFromUint(index),
-                                 value, language_mode);
-}
-
-
 MaybeHandle<Object> Object::RedefineNonconfigurableProperty(
     Isolate* isolate, Handle<Object> name, Handle<Object> value,
     LanguageMode language_mode) {
@@ -3262,11 +3251,12 @@ MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it,
   MaybeHandle<Object> maybe_old;
   if (is_observed) maybe_old = it->GetDataValue();
 
+  Handle<Object> to_assign = value;
   // Convert the incoming value to a number for storing into typed arrays.
   if (it->IsElement() && (receiver->HasExternalArrayElements() ||
                           receiver->HasFixedTypedArrayElements())) {
     if (!value->IsNumber() && !value->IsUndefined()) {
-      ASSIGN_RETURN_ON_EXCEPTION(it->isolate(), value,
+      ASSIGN_RETURN_ON_EXCEPTION(it->isolate(), to_assign,
                                  Execution::ToNumber(it->isolate(), value),
                                  Object);
     }
@@ -3274,10 +3264,10 @@ MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it,
 
   // Possibly migrate to the most up-to-date map that will be able to store
   // |value| under it->name().
-  it->PrepareForDataProperty(value);
+  it->PrepareForDataProperty(to_assign);
 
   // Write the property value.
-  value = it->WriteDataValue(value);
+  it->WriteDataValue(to_assign);
 
   // Send the change record if there are observers.
   if (is_observed && !value->SameValue(*maybe_old.ToHandleChecked())) {
@@ -4254,7 +4244,7 @@ MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
   DCHECK(!value->IsTheHole());
   LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
   if (it.state() == LookupIterator::ACCESS_CHECK) {
-    if (!it.isolate()->MayAccess(object)) {
+    if (!it.HasAccess()) {
       return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY);
     }
     it.Next();
@@ -4277,7 +4267,7 @@ MaybeHandle<Object> JSObject::SetOwnElementIgnoreAttributes(
   LookupIterator it(isolate, object, index,
                     LookupIterator::OWN_SKIP_INTERCEPTOR);
   if (it.state() == LookupIterator::ACCESS_CHECK) {
-    if (!isolate->MayAccess(object)) {
+    if (!it.HasAccess()) {
       return SetPropertyWithFailedAccessCheck(&it, value, STRICT);
     }
     it.Next();
index bd9e4abe71354c1936cb5bac273dfa645fc2a0cb..5ce906152bf6e4b886dc2fe3d250ac6ad159cc98 100644 (file)
@@ -1176,9 +1176,6 @@ class Object {
   MUST_USE_RESULT static MaybeHandle<Object> WriteToReadOnlyProperty(
       Isolate* isolate, Handle<Object> reciever, Handle<Object> name,
       Handle<Object> value, LanguageMode language_mode);
-  MUST_USE_RESULT static MaybeHandle<Object> WriteToReadOnlyElement(
-      Isolate* isolate, Handle<Object> receiver, uint32_t index,
-      Handle<Object> value, LanguageMode language_mode);
   MUST_USE_RESULT static MaybeHandle<Object> RedefineNonconfigurableProperty(
       Isolate* isolate, Handle<Object> name, Handle<Object> value,
       LanguageMode language_mode);
@@ -1841,6 +1838,12 @@ class JSObject: public JSReceiver {
   MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithInterceptor(
       LookupIterator* it, Handle<Object> value);
 
+  // Calls SetOwn[Property|Element]IgnoreAttributes depending on whether name is
+  // convertible to an index.
+  MUST_USE_RESULT static inline MaybeHandle<Object> DefinePropertyOrElement(
+      Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
+      PropertyAttributes attributes = NONE);
+
   MUST_USE_RESULT static MaybeHandle<Object> SetOwnPropertyIgnoreAttributes(
       Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
       PropertyAttributes attributes);
@@ -4045,7 +4048,7 @@ class ScopeInfo : public FixedArray {
   FunctionKind function_kind();
 
   // Copies all the context locals into an object used to materialize a scope.
-  static bool CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
+  static void CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
                                              Handle<Context> context,
                                              Handle<JSObject> scope_object);
 
index 3dbcc65eca6af1e5e5e9a0f80009d18dd8a73640..fe76dfa0dd2564c9787cb9d806084cb74eea4f23 100644 (file)
@@ -200,16 +200,8 @@ RUNTIME_FUNCTION(Runtime_DefineClassMethod) {
   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 2);
 
-  uint32_t index;
-  if (name->AsArrayIndex(&index)) {
-    RETURN_FAILURE_ON_EXCEPTION(
-        isolate, JSObject::SetOwnElementIgnoreAttributes(object, index,
-                                                         function, DONT_ENUM));
-  } else {
-    RETURN_FAILURE_ON_EXCEPTION(
-        isolate, JSObject::SetOwnPropertyIgnoreAttributes(object, name,
-                                                          function, DONT_ENUM));
-  }
+  RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::DefinePropertyOrElement(
+                                           object, name, function, DONT_ENUM));
   return isolate->heap()->undefined_value();
 }
 
index 2555086b07e2265ad7da2b00088bdf316b804d5c..5ae797986eefdb93bd0897f7bd2990d30bf09ef1 100644 (file)
@@ -861,11 +861,10 @@ static bool ParameterIsShadowedByContextLocal(Handle<ScopeInfo> info,
 }
 
 
-MUST_USE_RESULT
-static MaybeHandle<Context> MaterializeReceiver(Isolate* isolate,
-                                                Handle<Context> target,
-                                                Handle<JSFunction> function,
-                                                JavaScriptFrame* frame) {
+static Handle<Context> MaterializeReceiver(Isolate* isolate,
+                                           Handle<Context> target,
+                                           Handle<JSFunction> function,
+                                           JavaScriptFrame* frame) {
   Handle<SharedFunctionInfo> shared(function->shared());
   Handle<ScopeInfo> scope_info(shared->scope_info());
   Handle<Object> receiver;
@@ -882,14 +881,14 @@ static MaybeHandle<Context> MaterializeReceiver(Isolate* isolate,
               &init_flag, &maybe_assigned_flag) >= 0) {
         return target;
       }
-      receiver = Handle<Object>(frame->receiver(), isolate);
+      receiver = handle(frame->receiver(), isolate);
       break;
     }
     case MODULE_SCOPE:
       receiver = isolate->factory()->undefined_value();
       break;
     case SCRIPT_SCOPE:
-      receiver = Handle<Object>(function->global_proxy(), isolate);
+      receiver = handle(function->global_proxy(), isolate);
       break;
     default:
       // For eval code, arrow functions, and the like, there's no "this" binding
@@ -904,8 +903,7 @@ static MaybeHandle<Context> MaterializeReceiver(Isolate* isolate,
 
 // Create a plain JSObject which materializes the local scope for the specified
 // frame.
-MUST_USE_RESULT
-static MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector(
+static void MaterializeStackLocalsWithFrameInspector(
     Isolate* isolate, Handle<JSObject> target, Handle<ScopeInfo> scope_info,
     FrameInspector* frame_inspector) {
   // First fill all parameters.
@@ -923,9 +921,7 @@ static MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector(
                          isolate);
     DCHECK(!value->IsTheHole());
 
-    RETURN_ON_EXCEPTION(isolate, Runtime::SetObjectProperty(
-                                     isolate, target, name, value, SLOPPY),
-                        JSObject);
+    JSObject::SetOwnPropertyIgnoreAttributes(target, name, value, NONE).Check();
   }
 
   // Second fill all stack locals.
@@ -939,23 +935,18 @@ static MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector(
       value = isolate->factory()->undefined_value();
     }
 
-    RETURN_ON_EXCEPTION(isolate, Runtime::SetObjectProperty(
-                                     isolate, target, name, value, SLOPPY),
-                        JSObject);
+    JSObject::SetOwnPropertyIgnoreAttributes(target, name, value, NONE).Check();
   }
-
-  return target;
 }
 
-MUST_USE_RESULT
-static MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector(
+static void MaterializeStackLocalsWithFrameInspector(
     Isolate* isolate, Handle<JSObject> target, Handle<JSFunction> function,
     FrameInspector* frame_inspector) {
   Handle<SharedFunctionInfo> shared(function->shared());
   Handle<ScopeInfo> scope_info(shared->scope_info());
 
-  return MaterializeStackLocalsWithFrameInspector(isolate, target, scope_info,
-                                                  frame_inspector);
+  MaterializeStackLocalsWithFrameInspector(isolate, target, scope_info,
+                                           frame_inspector);
 }
 
 
@@ -1008,10 +999,8 @@ MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext(
   // Third fill all context locals.
   Handle<Context> frame_context(Context::cast(frame->context()));
   Handle<Context> function_context(frame_context->declaration_context());
-  if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, function_context,
-                                                 target)) {
-    return MaybeHandle<JSObject>();
-  }
+  ScopeInfo::CopyContextLocalsToScopeObject(scope_info, function_context,
+                                            target);
 
   // Finally copy any properties from the function context extension.
   // These will be variables introduced by eval.
@@ -1056,10 +1045,8 @@ MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScriptScope(
     Handle<Context> context =
         ScriptContextTable::GetContext(script_contexts, context_index);
     Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
-    if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context,
-                                                   script_scope)) {
-      return MaybeHandle<JSObject>();
-    }
+    ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context,
+                                              script_scope);
   }
   return script_scope;
 }
@@ -1072,11 +1059,8 @@ MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope(
 
   Handle<JSObject> local_scope =
       isolate->factory()->NewJSObject(isolate->object_function());
-  ASSIGN_RETURN_ON_EXCEPTION(
-      isolate, local_scope,
-      MaterializeStackLocalsWithFrameInspector(isolate, local_scope, function,
-                                               &frame_inspector),
-      JSObject);
+  MaterializeStackLocalsWithFrameInspector(isolate, local_scope, function,
+                                           &frame_inspector);
 
   return MaterializeLocalContext(isolate, local_scope, function, frame);
 }
@@ -1196,8 +1180,8 @@ static bool SetBlockVariableValue(Isolate* isolate,
 
 // Create a plain JSObject which materializes the closure content for the
 // context.
-MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeClosure(
-    Isolate* isolate, Handle<Context> context) {
+static Handle<JSObject> MaterializeClosure(Isolate* isolate,
+                                           Handle<Context> context) {
   DCHECK(context->IsFunctionContext());
 
   Handle<SharedFunctionInfo> shared(context->closure()->shared());
@@ -1209,31 +1193,24 @@ MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeClosure(
       isolate->factory()->NewJSObject(isolate->object_function());
 
   // Fill all context locals to the context extension.
-  if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context,
-                                                 closure_scope)) {
-    return MaybeHandle<JSObject>();
-  }
+  ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context, closure_scope);
 
   // Finally copy any properties from the function context extension. This will
   // be variables introduced by eval.
   if (context->has_extension()) {
     Handle<JSObject> ext(JSObject::cast(context->extension()));
-    Handle<FixedArray> keys;
-    ASSIGN_RETURN_ON_EXCEPTION(
-        isolate, keys, JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS),
-        JSObject);
+    DCHECK(ext->IsJSContextExtensionObject());
+    Handle<FixedArray> keys =
+        JSReceiver::GetKeys(ext, JSReceiver::OWN_ONLY).ToHandleChecked();
 
     for (int i = 0; i < keys->length(); i++) {
       HandleScope scope(isolate);
       // Names of variables introduced by eval are strings.
       DCHECK(keys->get(i)->IsString());
       Handle<String> key(String::cast(keys->get(i)));
-      Handle<Object> value;
-      ASSIGN_RETURN_ON_EXCEPTION(
-          isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
-      RETURN_ON_EXCEPTION(isolate, Runtime::DefineObjectProperty(
-                                       closure_scope, key, value, NONE),
-                          JSObject);
+      Handle<Object> value = Object::GetProperty(ext, key).ToHandleChecked();
+      JSObject::SetOwnPropertyIgnoreAttributes(closure_scope, key, value, NONE)
+          .Check();
     }
   }
 
@@ -1260,12 +1237,13 @@ static bool SetClosureVariableValue(Isolate* isolate, Handle<Context> context,
   // be variables introduced by eval.
   if (context->has_extension()) {
     Handle<JSObject> ext(JSObject::cast(context->extension()));
-    Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
+    DCHECK(ext->IsJSContextExtensionObject());
+    Maybe<bool> maybe = JSReceiver::HasOwnProperty(ext, variable_name);
     DCHECK(maybe.IsJust());
     if (maybe.FromJust()) {
       // We don't expect this to do anything except replacing property value.
-      Runtime::DefineObjectProperty(ext, variable_name, new_value, NONE)
-          .Assert();
+      JSObject::SetOwnPropertyIgnoreAttributes(ext, variable_name, new_value,
+                                               NONE).Check();
       return true;
     }
   }
@@ -1294,17 +1272,16 @@ static bool SetScriptVariableValue(Handle<Context> context,
 
 // Create a plain JSObject which materializes the scope for the specified
 // catch context.
-MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope(
-    Isolate* isolate, Handle<Context> context) {
+static Handle<JSObject> MaterializeCatchScope(Isolate* isolate,
+                                              Handle<Context> context) {
   DCHECK(context->IsCatchContext());
   Handle<String> name(String::cast(context->extension()));
   Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
                                isolate);
   Handle<JSObject> catch_scope =
       isolate->factory()->NewJSObject(isolate->object_function());
-  RETURN_ON_EXCEPTION(isolate, Runtime::DefineObjectProperty(
-                                   catch_scope, name, thrown_object, NONE),
-                      JSObject);
+  JSObject::SetOwnPropertyIgnoreAttributes(catch_scope, name, thrown_object,
+                                           NONE).Check();
   return catch_scope;
 }
 
@@ -1324,28 +1301,26 @@ static bool SetCatchVariableValue(Isolate* isolate, Handle<Context> context,
 
 // Create a plain JSObject which materializes the block scope for the specified
 // block context.
-MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope(
-    Isolate* isolate, Handle<ScopeInfo> scope_info, Handle<Context> context,
-    JavaScriptFrame* frame, int inlined_jsframe_index) {
+static Handle<JSObject> MaterializeBlockScope(Isolate* isolate,
+                                              Handle<ScopeInfo> scope_info,
+                                              Handle<Context> context,
+                                              JavaScriptFrame* frame,
+                                              int inlined_jsframe_index) {
   Handle<JSObject> block_scope =
       isolate->factory()->NewJSObject(isolate->object_function());
 
   if (frame != nullptr) {
     FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
-    RETURN_ON_EXCEPTION(isolate,
-                        MaterializeStackLocalsWithFrameInspector(
-                            isolate, block_scope, scope_info, &frame_inspector),
-                        JSObject);
+    MaterializeStackLocalsWithFrameInspector(isolate, block_scope, scope_info,
+                                             &frame_inspector);
   }
 
   if (!context.is_null()) {
     Handle<ScopeInfo> scope_info_from_context(
         ScopeInfo::cast(context->extension()));
     // Fill all context locals.
-    if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info_from_context,
-                                                   context, block_scope)) {
-      return MaybeHandle<JSObject>();
-    }
+    ScopeInfo::CopyContextLocalsToScopeObject(scope_info_from_context, context,
+                                              block_scope);
   }
 
   return block_scope;
@@ -1365,10 +1340,7 @@ MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope(
       isolate->factory()->NewJSObject(isolate->object_function());
 
   // Fill all context locals.
-  if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context,
-                                                 module_scope)) {
-    return MaybeHandle<JSObject>();
-  }
+  ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context, module_scope);
 
   return module_scope;
 }
@@ -2396,24 +2368,23 @@ RUNTIME_FUNCTION(Runtime_ClearStepping) {
 
 // Helper function to find or create the arguments object for
 // Runtime_DebugEvaluate.
-MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject(
-    Isolate* isolate, Handle<JSObject> target, Handle<JSFunction> function) {
+static void MaterializeArgumentsObject(Isolate* isolate,
+                                       Handle<JSObject> target,
+                                       Handle<JSFunction> function) {
   // Do not materialize the arguments object for eval or top-level code.
   // Skip if "arguments" is already taken.
-  if (!function->shared()->is_function()) return target;
+  if (!function->shared()->is_function()) return;
   Maybe<bool> maybe = JSReceiver::HasOwnProperty(
       target, isolate->factory()->arguments_string());
-  if (!maybe.IsJust()) return MaybeHandle<JSObject>();
-  if (maybe.FromJust()) return target;
+  DCHECK(maybe.IsJust());
+  if (maybe.FromJust()) return;
 
   // FunctionGetArguments can't throw an exception.
   Handle<JSObject> arguments =
       Handle<JSObject>::cast(Accessors::FunctionGetArguments(function));
   Handle<String> arguments_str = isolate->factory()->arguments_string();
-  RETURN_ON_EXCEPTION(isolate, Runtime::DefineObjectProperty(
-                                   target, arguments_str, arguments, NONE),
-                      JSObject);
-  return target;
+  JSObject::SetOwnPropertyIgnoreAttributes(target, arguments_str, arguments,
+                                           NONE).Check();
 }
 
 
@@ -2510,22 +2481,16 @@ class EvaluationContextBuilder {
 
         // The "this" binding, if any, can't be bound via "with".  If we need
         // to, add another node onto the outer context to bind "this".
-        if (!MaterializeReceiver(isolate, parent_context, function, frame)
-                 .ToHandle(&parent_context))
-          return;
+        parent_context =
+            MaterializeReceiver(isolate, parent_context, function, frame);
 
         Handle<JSObject> materialized_function =
             NewJSObjectWithNullProto(isolate);
 
-        if (!MaterializeStackLocalsWithFrameInspector(
-                 isolate, materialized_function, function, &frame_inspector)
-                 .ToHandle(&materialized_function))
-          return;
+        MaterializeStackLocalsWithFrameInspector(isolate, materialized_function,
+                                                 function, &frame_inspector);
 
-        if (!MaterializeArgumentsObject(isolate, materialized_function,
-                                        function)
-                 .ToHandle(&materialized_function))
-          return;
+        MaterializeArgumentsObject(isolate, materialized_function, function);
 
         Handle<Context> with_context = isolate->factory()->NewWithContext(
             function, parent_context, materialized_function);
@@ -2553,10 +2518,9 @@ class EvaluationContextBuilder {
       } else if (scope_type == ScopeIterator::ScopeTypeBlock) {
         Handle<JSObject> materialized_object =
             NewJSObjectWithNullProto(isolate);
-        if (!MaterializeStackLocalsWithFrameInspector(
-                 isolate, materialized_object, it.CurrentScopeInfo(),
-                 &frame_inspector).ToHandle(&materialized_object))
-          return;
+        MaterializeStackLocalsWithFrameInspector(isolate, materialized_object,
+                                                 it.CurrentScopeInfo(),
+                                                 &frame_inspector);
         if (it.HasContext()) {
           Handle<Context> cloned_context =
               Handle<Context>::cast(FixedArray::CopySize(
index 956fee9e838f46214ed47b017e7a0a226efedf99..1bf405a1d9a9bd4d533a354ee45252b972102bf9 100644 (file)
@@ -92,98 +92,13 @@ MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
         Object);
   }
 
-  if (object->IsJSProxy()) {
-    Handle<Object> name_object;
-    if (key->IsSymbol()) {
-      name_object = key;
-    } else {
-      ASSIGN_RETURN_ON_EXCEPTION(isolate, name_object,
-                                 Execution::ToString(isolate, key), Object);
-    }
-    Handle<Name> name = Handle<Name>::cast(name_object);
-    return Object::SetProperty(Handle<JSProxy>::cast(object), name, value,
-                               language_mode);
-  }
-
-  // Check if the given key is an array index.
-  uint32_t index = 0;
-  if (key->ToArrayIndex(&index)) {
-    // TODO(verwaest): Support non-JSObject receivers.
-    if (!object->IsJSObject()) return value;
-    Handle<JSObject> js_object = Handle<JSObject>::cast(object);
-
-    // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
-    // of a string using [] notation.  We need to support this too in
-    // JavaScript.
-    // In the case of a String object we just need to redirect the assignment to
-    // the underlying string if the index is in range.  Since the underlying
-    // string does nothing with the assignment then we can ignore such
-    // assignments.
-    if (js_object->IsStringObjectWithCharacterAt(index)) {
-      return value;
-    }
-
-    JSObject::ValidateElements(js_object);
-    if (js_object->HasExternalArrayElements() ||
-        js_object->HasFixedTypedArrayElements()) {
-      if (!value->IsNumber() && !value->IsUndefined()) {
-        ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
-                                   Execution::ToNumber(isolate, value), Object);
-      }
-    }
-
-    MaybeHandle<Object> result =
-        JSObject::SetElement(js_object, index, value, language_mode);
-    JSObject::ValidateElements(js_object);
-
-    return result.is_null() ? result : value;
-  }
-
-  if (key->IsName()) {
-    Handle<Name> name = Handle<Name>::cast(key);
-    if (name->AsArrayIndex(&index)) {
-      // TODO(verwaest): Support non-JSObject receivers.
-      if (!object->IsJSObject()) return value;
-      Handle<JSObject> js_object = Handle<JSObject>::cast(object);
-      if (js_object->HasExternalArrayElements()) {
-        if (!value->IsNumber() && !value->IsUndefined()) {
-          ASSIGN_RETURN_ON_EXCEPTION(
-              isolate, value, Execution::ToNumber(isolate, value), Object);
-        }
-      }
-      return JSObject::SetElement(js_object, index, value, language_mode);
-    } else {
-      if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
-      return Object::SetProperty(object, name, value, language_mode);
-    }
-  }
-
-  // Call-back into JavaScript to convert the key to a string.
-  Handle<Object> converted;
-  ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
-                             Execution::ToString(isolate, key), Object);
-  Handle<String> name = Handle<String>::cast(converted);
-
-  if (name->AsArrayIndex(&index)) {
-    // TODO(verwaest): Support non-JSObject receivers.
-    if (!object->IsJSObject()) return value;
-    Handle<JSObject> js_object = Handle<JSObject>::cast(object);
-    return JSObject::SetElement(js_object, index, value, language_mode);
-  }
-  return Object::SetProperty(object, name, value, language_mode);
-}
-
-
-MaybeHandle<Object> Runtime::DefineObjectProperty(Handle<JSObject> js_object,
-                                                  Handle<Object> key,
-                                                  Handle<Object> value,
-                                                  PropertyAttributes attrs) {
-  Isolate* isolate = js_object->GetIsolate();
   // Check if the given key is an array index.
   uint32_t index = 0;
   if (key->ToArrayIndex(&index)) {
-    return JSObject::SetOwnElementIgnoreAttributes(js_object, index, value,
-                                                   attrs);
+    // TODO(verwaest): Support other objects as well.
+    if (!object->IsJSReceiver()) return value;
+    return JSReceiver::SetElement(Handle<JSReceiver>::cast(object), index,
+                                  value, language_mode);
   }
 
   Handle<Name> name;
@@ -198,13 +113,12 @@ MaybeHandle<Object> Runtime::DefineObjectProperty(Handle<JSObject> js_object,
   }
 
   if (name->AsArrayIndex(&index)) {
-    return JSObject::SetOwnElementIgnoreAttributes(js_object, index, value,
-                                                   attrs);
-  } else {
-    if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
-    return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value,
-                                                    attrs);
+    // TODO(verwaest): Support other objects as well.
+    if (!object->IsJSReceiver()) return value;
+    return JSReceiver::SetElement(Handle<JSReceiver>::cast(object), index,
+                                  value, language_mode);
   }
+  return Object::SetProperty(object, name, value, language_mode);
 }
 
 
@@ -1355,23 +1269,27 @@ RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
 RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
   CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
 
-  LookupIterator it(js_object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
-  if (it.IsFound() && it.state() == LookupIterator::ACCESS_CHECK) {
-    if (!isolate->MayAccess(js_object)) {
-      return isolate->heap()->undefined_value();
-    }
-    it.Next();
+  uint32_t index = 0;
+  LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR;
+  LookupIterator it = name->AsArrayIndex(&index)
+                          ? LookupIterator(isolate, object, index, c)
+                          : LookupIterator(object, name, c);
+  if (it.state() == LookupIterator::ACCESS_CHECK && !it.HasAccess()) {
+    return isolate->heap()->undefined_value();
   }
 
   Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      Runtime::DefineObjectProperty(js_object, name, obj_value, attrs));
+  MaybeHandle<Object> maybe_result =
+      it.IsElement()
+          ? JSObject::SetOwnElementIgnoreAttributes(object, index, value, attrs)
+          : JSObject::SetOwnPropertyIgnoreAttributes(object, name, value,
+                                                     attrs);
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
   return *result;
 }
 
@@ -1381,8 +1299,8 @@ RUNTIME_FUNCTION(Runtime_GetDataProperty) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 2);
   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
-  return *JSReceiver::GetDataProperty(object, key);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+  return *JSReceiver::GetDataProperty(object, name);
 }
 
 
index 86502ee6ea4271049ebbd337303991c90e32bd1a..b855ca5ac949ceccef075d7db70f886ead930cf2 100644 (file)
@@ -822,10 +822,6 @@ class Runtime : public AllStatic {
       Isolate* isolate, Handle<Object> object, Handle<Object> key,
       Handle<Object> value, LanguageMode language_mode);
 
-  MUST_USE_RESULT static MaybeHandle<Object> DefineObjectProperty(
-      Handle<JSObject> object, Handle<Object> key, Handle<Object> value,
-      PropertyAttributes attr);
-
   MUST_USE_RESULT static MaybeHandle<Object> GetObjectProperty(
       Isolate* isolate, Handle<Object> object, Handle<Object> key);
 
index b819b172c4ad1db78926b0d59dc253d9841de94f..f91df650800cb432abdef22d98cc3b29d6b2e1a1 100644 (file)
@@ -505,12 +505,12 @@ FunctionKind ScopeInfo::function_kind() {
 }
 
 
-bool ScopeInfo::CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
+void ScopeInfo::CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
                                                Handle<Context> context,
                                                Handle<JSObject> scope_object) {
   Isolate* isolate = scope_info->GetIsolate();
   int local_count = scope_info->ContextLocalCount();
-  if (local_count == 0) return true;
+  if (local_count == 0) return;
   // Fill all context locals to the context extension.
   int first_context_var = scope_info->StackLocalCount();
   int start = scope_info->ContextLocalNameEntriesIndex();
@@ -520,14 +520,12 @@ bool ScopeInfo::CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
     Handle<Object> value = Handle<Object>(context->get(context_index), isolate);
     // Reflect variables under TDZ as undefined in scope object.
     if (value->IsTheHole()) continue;
-    RETURN_ON_EXCEPTION_VALUE(
-        isolate, Runtime::DefineObjectProperty(
-                     scope_object,
-                     Handle<String>(String::cast(scope_info->get(i + start))),
-                     value, ::NONE),
-        false);
+    // This should always succeed.
+    // TODO(verwaest): Use AddDataProperty instead.
+    JSObject::SetOwnPropertyIgnoreAttributes(
+        scope_object, handle(String::cast(scope_info->get(i + start))), value,
+        ::NONE).Check();
   }
-  return true;
 }
 
 
index 59b2bad9ca2037c3f1c78f2176836e2a5d2f4766..25a75103e3704e5f7938877b8d56fee2ea9b2ffc 100644 (file)
@@ -115,8 +115,9 @@ class DebugLocalContext {
         v8::Utils::OpenHandle(*context_->Global())));
     Handle<v8::internal::String> debug_string =
         factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("debug"));
-    v8::internal::Runtime::DefineObjectProperty(global, debug_string,
-        handle(debug_context->global_proxy(), isolate), DONT_ENUM).Check();
+    v8::internal::JSObject::SetOwnPropertyIgnoreAttributes(
+        global, debug_string, handle(debug_context->global_proxy()), DONT_ENUM)
+        .Check();
   }
 
  private: