Add v8::Object::GetRealNamedPropertyAttributes()

Add v8::Object::GetRealNamedPropertyAttributes() and
v8::Object::GetRealNamedPropertyAttributesInPrototypeChain().

See https://github.com/iojs/io.js/issues/864 for background.

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

Cr-Commit-Position: refs/heads/master@{#26855}
This commit is contained in:
ben 2015-02-25 07:09:11 -08:00 committed by Commit bot
parent c094da9233
commit 726eb0582b
3 changed files with 80 additions and 1 deletions

View File

@ -2617,6 +2617,14 @@ class V8_EXPORT Object : public Value {
*/
Local<Value> GetRealNamedPropertyInPrototypeChain(Handle<String> key);
/**
* Gets the property attributes of a real property in the prototype chain,
* which can be None or any combination of ReadOnly, DontEnum and DontDelete.
* Interceptors in the prototype chain are not called.
*/
Maybe<PropertyAttribute> GetRealNamedPropertyAttributesInPrototypeChain(
Handle<String> key);
/**
* If result.IsEmpty() no real property was located on the object or
* in the prototype chain.
@ -2624,6 +2632,13 @@ class V8_EXPORT Object : public Value {
*/
Local<Value> GetRealNamedProperty(Handle<String> key);
/**
* Gets the property attributes of a real property which can be
* None or any combination of ReadOnly, DontEnum and DontDelete.
* Interceptors in the prototype chain are not called.
*/
Maybe<PropertyAttribute> GetRealNamedPropertyAttributes(Handle<String> key);
/** Tests for a named lookup interceptor.*/
bool HasNamedLookupInterceptor();

View File

@ -3756,6 +3756,14 @@ static Local<Value> GetPropertyByLookup(i::LookupIterator* it) {
}
static Maybe<PropertyAttribute> GetPropertyAttributesByLookup(
i::LookupIterator* it) {
Maybe<PropertyAttributes> attr = i::JSReceiver::GetPropertyAttributes(it);
if (!it->IsFound()) return Maybe<PropertyAttribute>();
return Maybe<PropertyAttribute>(static_cast<PropertyAttribute>(attr.value));
}
Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
Handle<String> key) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
@ -3774,6 +3782,24 @@ Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
}
Maybe<PropertyAttribute>
v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(Handle<String> key) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate,
"v8::Object::GetRealNamedPropertyAttributesInPrototypeChain()",
return Maybe<PropertyAttribute>());
ENTER_V8(isolate);
i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
i::PrototypeIterator iter(isolate, self_obj);
if (iter.IsAtEnd()) return Maybe<PropertyAttribute>();
i::Handle<i::Object> proto = i::PrototypeIterator::GetCurrent(iter);
i::LookupIterator it(self_obj, key_obj, i::Handle<i::JSReceiver>::cast(proto),
i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
return GetPropertyAttributesByLookup(&it);
}
Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
@ -3787,6 +3813,20 @@ Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
}
Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
Handle<String> key) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ON_BAILOUT(isolate, "v8::Object::GetRealNamedPropertyAttributes()",
return Maybe<PropertyAttribute>());
ENTER_V8(isolate);
i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
i::LookupIterator it(self_obj, key_obj,
i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
return GetPropertyAttributesByLookup(&it);
}
// Turns on access checks by copying the map and setting the check flag.
// Because the object gets a new map, existing inline cache caching
// the old map of this object will fail.

View File

@ -61,12 +61,15 @@ using ::v8::FunctionTemplate;
using ::v8::Handle;
using ::v8::HandleScope;
using ::v8::Local;
using ::v8::Name;
using ::v8::Maybe;
using ::v8::Message;
using ::v8::MessageCallback;
using ::v8::Name;
using ::v8::None;
using ::v8::Object;
using ::v8::ObjectTemplate;
using ::v8::Persistent;
using ::v8::PropertyAttribute;
using ::v8::Script;
using ::v8::StackTrace;
using ::v8::String;
@ -10869,16 +10872,32 @@ THREADED_TEST(VariousGetPropertiesAndThrowingCallbacks) {
try_catch.Reset();
CHECK(result.IsEmpty());
Maybe<PropertyAttribute> attr =
instance->GetRealNamedPropertyAttributes(v8_str("f"));
CHECK(!try_catch.HasCaught());
CHECK(attr.has_value);
CHECK_EQ(attr.value, None);
result = another->GetRealNamedProperty(v8_str("f"));
CHECK(try_catch.HasCaught());
try_catch.Reset();
CHECK(result.IsEmpty());
attr = another->GetRealNamedPropertyAttributes(v8_str("f"));
CHECK(!try_catch.HasCaught());
CHECK(attr.has_value);
CHECK_EQ(attr.value, None);
result = another->GetRealNamedPropertyInPrototypeChain(v8_str("f"));
CHECK(try_catch.HasCaught());
try_catch.Reset();
CHECK(result.IsEmpty());
attr = another->GetRealNamedPropertyAttributesInPrototypeChain(v8_str("f"));
CHECK(!try_catch.HasCaught());
CHECK(attr.has_value);
CHECK_EQ(attr.value, None);
result = another->Get(v8_str("f"));
CHECK(try_catch.HasCaught());
try_catch.Reset();
@ -10889,6 +10908,11 @@ THREADED_TEST(VariousGetPropertiesAndThrowingCallbacks) {
try_catch.Reset();
CHECK(result.IsEmpty());
attr = with_js_getter->GetRealNamedPropertyAttributes(v8_str("f"));
CHECK(!try_catch.HasCaught());
CHECK(attr.has_value);
CHECK_EQ(attr.value, None);
result = with_js_getter->Get(v8_str("f"));
CHECK(try_catch.HasCaught());
try_catch.Reset();