Commit 1da951ad authored by Hitoshi Yoshida's avatar Hitoshi Yoshida Committed by Commit Bot

Create a new API Object::SetNativeDataProperty

This new API sets a native data property on an object
directly, as Template::SetNativeDataProperty does.
It is similar to Object::SetAccessor, but properties
set by SetNativeDataProperty without kReadOnly flag
can be replaced.


Bug:chromium:617892

Change-Id: I32973f7190906d76be6802da9a0489edce0bd93e
Reviewed-on: https://chromium-review.googlesource.com/479474Reviewed-by: 's avatarJochen Eisinger <jochen@chromium.org>
Commit-Queue: Hitoshi Yoshida <peria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44716}
parent 2a2a417b
......@@ -3145,6 +3145,16 @@ class V8_EXPORT Object : public Value {
PropertyAttribute attribute = None,
AccessControl settings = DEFAULT);
/**
* Sets a native data property like Template::SetNativeDataProperty, but
* this method sets on this object directly.
*/
V8_WARN_UNUSED_RESULT Maybe<bool> SetNativeDataProperty(
Local<Context> context, Local<Name> name,
AccessorNameGetterCallback getter,
AccessorNameSetterCallback setter = nullptr,
Local<Value> data = Local<Value>(), PropertyAttribute attributes = None);
/**
* Functionality for private properties.
* This is an experimental feature, use at your own risk.
......
......@@ -4782,21 +4782,20 @@ bool v8::Object::Has(uint32_t index) {
return Has(context, index).FromMaybe(false);
}
template <typename Getter, typename Setter, typename Data>
static Maybe<bool> ObjectSetAccessor(Local<Context> context, Object* self,
Local<Name> name, Getter getter,
Setter setter, Data data,
AccessControl settings,
PropertyAttribute attributes) {
PropertyAttribute attributes,
bool is_special_data_property) {
PREPARE_FOR_EXECUTION_PRIMITIVE(context, Object, SetAccessor, bool);
if (!Utils::OpenHandle(self)->IsJSObject()) return Just(false);
i::Handle<i::JSObject> obj =
i::Handle<i::JSObject>::cast(Utils::OpenHandle(self));
v8::Local<AccessorSignature> signature;
auto info =
MakeAccessorInfo(name, getter, setter, data, settings, attributes,
signature, i::FLAG_disable_old_api_accessors, false);
auto info = MakeAccessorInfo(name, getter, setter, data, settings, attributes,
signature, is_special_data_property, false);
if (info.is_null()) return Nothing<bool>();
bool fast = obj->HasFastProperties();
i::Handle<i::Object> result;
......@@ -4817,7 +4816,8 @@ Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name,
MaybeLocal<Value> data, AccessControl settings,
PropertyAttribute attribute) {
return ObjectSetAccessor(context, this, name, getter, setter,
data.FromMaybe(Local<Value>()), settings, attribute);
data.FromMaybe(Local<Value>()), settings, attribute,
i::FLAG_disable_old_api_accessors);
}
......@@ -4826,7 +4826,8 @@ bool Object::SetAccessor(Local<String> name, AccessorGetterCallback getter,
AccessControl settings, PropertyAttribute attributes) {
auto context = ContextFromHeapObject(Utils::OpenHandle(this));
return ObjectSetAccessor(context, this, name, getter, setter, data, settings,
attributes).FromMaybe(false);
attributes, i::FLAG_disable_old_api_accessors)
.FromMaybe(false);
}
......@@ -4836,7 +4837,8 @@ bool Object::SetAccessor(Local<Name> name, AccessorNameGetterCallback getter,
PropertyAttribute attributes) {
auto context = ContextFromHeapObject(Utils::OpenHandle(this));
return ObjectSetAccessor(context, this, name, getter, setter, data, settings,
attributes).FromMaybe(false);
attributes, i::FLAG_disable_old_api_accessors)
.FromMaybe(false);
}
......@@ -4859,6 +4861,15 @@ void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
static_cast<i::PropertyAttributes>(attribute));
}
Maybe<bool> Object::SetNativeDataProperty(v8::Local<v8::Context> context,
v8::Local<Name> name,
AccessorNameGetterCallback getter,
AccessorNameSetterCallback setter,
v8::Local<Value> data,
PropertyAttribute attributes) {
return ObjectSetAccessor(context, this, name, getter, setter, data, DEFAULT,
attributes, true);
}
Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context,
Local<Name> key) {
......
......@@ -2938,6 +2938,7 @@ THREADED_TEST(SymbolProperties) {
v8::Local<v8::Symbol> sym1 = v8::Symbol::New(isolate);
v8::Local<v8::Symbol> sym2 = v8::Symbol::New(isolate, v8_str("my-symbol"));
v8::Local<v8::Symbol> sym3 = v8::Symbol::New(isolate, v8_str("sym3"));
v8::Local<v8::Symbol> sym4 = v8::Symbol::New(isolate, v8_str("native"));
CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
......@@ -3024,6 +3025,23 @@ THREADED_TEST(SymbolProperties) {
->Equals(env.local(), v8::Integer::New(isolate, 42))
.FromJust());
CHECK(obj->SetNativeDataProperty(env.local(), sym4, SymbolAccessorGetter)
.FromJust());
CHECK(obj->Get(env.local(), sym4).ToLocalChecked()->IsUndefined());
CHECK(obj->Set(env.local(), v8_str("accessor_native"),
v8::Integer::New(isolate, 123))
.FromJust());
CHECK_EQ(123, obj->Get(env.local(), sym4)
.ToLocalChecked()
->Int32Value(env.local())
.FromJust());
CHECK(obj->Set(env.local(), sym4, v8::Integer::New(isolate, 314)).FromJust());
CHECK(obj->Get(env.local(), sym4)
.ToLocalChecked()
->Equals(env.local(), v8::Integer::New(isolate, 314))
.FromJust());
CHECK(obj->Delete(env.local(), v8_str("accessor_native")).FromJust());
// Add another property and delete it afterwards to force the object in
// slow case.
CHECK(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment