diff --git a/src/api.cc b/src/api.cc index b881280008..c405b87538 100644 --- a/src/api.cc +++ b/src/api.cc @@ -3535,8 +3535,9 @@ Maybe v8::Object::CreateDataProperty(v8::Local context, if (it.IsFound() && !it.IsConfigurable()) return Just(false); - has_pending_exception = i::Runtime::DefineObjectProperty( - self, key_obj, value_obj, NONE).is_null(); + has_pending_exception = + i::Runtime::DefineObjectProperty(self, key_obj, value_obj, NONE, + i::JSObject::DONT_FORCE_FIELD).is_null(); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); return Just(true); } @@ -3573,9 +3574,10 @@ Maybe v8::Object::CreateDataProperty(v8::Local context, return Just(false); } - has_pending_exception = i::Runtime::DefineObjectProperty( - self, isolate->factory()->Uint32ToString(index), - value_obj, NONE).is_null(); + has_pending_exception = + i::Runtime::DefineObjectProperty( + self, isolate->factory()->Uint32ToString(index), value_obj, NONE, + i::JSObject::DONT_FORCE_FIELD).is_null(); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); return Just(true); } diff --git a/src/objects.cc b/src/objects.cc index c378ae9ff5..a497f55b7b 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -4133,7 +4133,8 @@ void ExecutableAccessorInfo::ClearSetter(Handle info) { MaybeHandle JSObject::ReconfigureAsDataProperty( - LookupIterator* it, Handle value, PropertyAttributes attributes) { + LookupIterator* it, Handle value, PropertyAttributes attributes, + ExecutableAccessorInfoHandling handling) { Handle object = Handle::cast(it->GetReceiver()); bool is_observed = object->map()->is_observed() && (it->IsElement() || @@ -4159,7 +4160,8 @@ MaybeHandle JSObject::ReconfigureAsDataProperty( // Special handling for ExecutableAccessorInfo, which behaves like a // data property. - if (accessors->IsExecutableAccessorInfo()) { + if (accessors->IsExecutableAccessorInfo() && + handling == DONT_FORCE_FIELD) { Handle result; ASSIGN_RETURN_ON_EXCEPTION( it->isolate(), result, @@ -4252,7 +4254,7 @@ MaybeHandle JSObject::ReconfigureAsDataProperty( // reconfigurable. MaybeHandle JSObject::SetOwnPropertyIgnoreAttributes( Handle object, Handle name, Handle value, - PropertyAttributes attributes) { + PropertyAttributes attributes, ExecutableAccessorInfoHandling handling) { DCHECK(!value->IsTheHole()); LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); if (it.state() == LookupIterator::ACCESS_CHECK) { @@ -4263,7 +4265,7 @@ MaybeHandle JSObject::SetOwnPropertyIgnoreAttributes( } if (it.IsFound()) { - return ReconfigureAsDataProperty(&it, value, attributes); + return ReconfigureAsDataProperty(&it, value, attributes, handling); } return AddDataProperty(&it, value, attributes, STRICT, @@ -4273,7 +4275,7 @@ MaybeHandle JSObject::SetOwnPropertyIgnoreAttributes( MaybeHandle JSObject::SetOwnElementIgnoreAttributes( Handle object, uint32_t index, Handle value, - PropertyAttributes attributes) { + PropertyAttributes attributes, ExecutableAccessorInfoHandling handling) { DCHECK(!object->HasExternalArrayElements()); Isolate* isolate = object->GetIsolate(); LookupIterator it(isolate, object, index, @@ -4286,7 +4288,7 @@ MaybeHandle JSObject::SetOwnElementIgnoreAttributes( } if (it.IsFound()) { - return ReconfigureAsDataProperty(&it, value, attributes); + return ReconfigureAsDataProperty(&it, value, attributes, handling); } return AddDataProperty(&it, value, attributes, STRICT, diff --git a/src/objects.h b/src/objects.h index bd9e4abe71..dc5b56e8c0 100644 --- a/src/objects.h +++ b/src/objects.h @@ -1841,16 +1841,23 @@ class JSObject: public JSReceiver { MUST_USE_RESULT static MaybeHandle SetPropertyWithInterceptor( LookupIterator* it, Handle value); + // SetLocalPropertyIgnoreAttributes converts callbacks to fields. We need to + // grant an exemption to ExecutableAccessor callbacks in some cases. + enum ExecutableAccessorInfoHandling { DEFAULT_HANDLING, DONT_FORCE_FIELD }; + MUST_USE_RESULT static MaybeHandle SetOwnPropertyIgnoreAttributes( Handle object, Handle name, Handle value, - PropertyAttributes attributes); + PropertyAttributes attributes, + ExecutableAccessorInfoHandling handling = DEFAULT_HANDLING); MUST_USE_RESULT static MaybeHandle SetOwnElementIgnoreAttributes( Handle object, uint32_t index, Handle value, - PropertyAttributes attributes); + PropertyAttributes attributes, + ExecutableAccessorInfoHandling handling = DEFAULT_HANDLING); MUST_USE_RESULT static MaybeHandle ReconfigureAsDataProperty( - LookupIterator* it, Handle value, PropertyAttributes attributes); + LookupIterator* it, Handle value, PropertyAttributes attributes, + ExecutableAccessorInfoHandling handling = DEFAULT_HANDLING); static void AddProperty(Handle object, Handle name, Handle value, PropertyAttributes attributes); diff --git a/src/runtime/runtime-object.cc b/src/runtime/runtime-object.cc index 956fee9e83..703bbedabe 100644 --- a/src/runtime/runtime-object.cc +++ b/src/runtime/runtime-object.cc @@ -174,16 +174,16 @@ MaybeHandle Runtime::SetObjectProperty(Isolate* isolate, } -MaybeHandle Runtime::DefineObjectProperty(Handle js_object, - Handle key, - Handle value, - PropertyAttributes attrs) { +MaybeHandle Runtime::DefineObjectProperty( + Handle js_object, Handle key, Handle value, + PropertyAttributes attrs, + JSObject::ExecutableAccessorInfoHandling handling) { 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); + attrs, handling); } Handle name; @@ -199,11 +199,11 @@ MaybeHandle Runtime::DefineObjectProperty(Handle js_object, if (name->AsArrayIndex(&index)) { return JSObject::SetOwnElementIgnoreAttributes(js_object, index, value, - attrs); + attrs, handling); } else { if (name->IsString()) name = String::Flatten(Handle::cast(name)); return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value, - attrs); + attrs, handling); } } @@ -1371,7 +1371,8 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) { Handle result; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, result, - Runtime::DefineObjectProperty(js_object, name, obj_value, attrs)); + Runtime::DefineObjectProperty(js_object, name, obj_value, attrs, + JSObject::DONT_FORCE_FIELD)); return *result; } diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 86502ee6ea..f45ce7d072 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -824,7 +824,9 @@ class Runtime : public AllStatic { MUST_USE_RESULT static MaybeHandle DefineObjectProperty( Handle object, Handle key, Handle value, - PropertyAttributes attr); + PropertyAttributes attr, + JSObject::ExecutableAccessorInfoHandling handling = + JSObject::DEFAULT_HANDLING); MUST_USE_RESULT static MaybeHandle GetObjectProperty( Isolate* isolate, Handle object, Handle key); diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 9ffefe81c7..4f6de5936b 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -13266,11 +13266,13 @@ TEST(ForceSet) { CHECK_EQ(3, global->Get(access_property)->Int32Value()); CHECK_EQ(1, force_set_set_count); CHECK_EQ(2, force_set_get_count); - // ForceSet does not remove the accessors, but rather calls the setter. + // ForceSet doesn't call the accessors for now. + // TODO(verwaest): Update once blink doesn't rely on ForceSet to delete api + // accessors. global->ForceSet(access_property, v8::Int32::New(isolate, 8)); - CHECK_EQ(3, global->Get(access_property)->Int32Value()); - CHECK_EQ(2, force_set_set_count); - CHECK_EQ(3, force_set_get_count); + CHECK_EQ(8, global->Get(access_property)->Int32Value()); + CHECK_EQ(1, force_set_set_count); + CHECK_EQ(2, force_set_get_count); }