Skip to content

Commit

Permalink
Add v8::Object::GetRealNamedPropertyAttributes()
Browse files Browse the repository at this point in the history
Add v8::Object::GetRealNamedPropertyAttributes() and
v8::Object::GetRealNamedPropertyAttributesInPrototypeChain().

See nodejs/node#864 for background.

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

Cr-Commit-Position: refs/heads/master@{#26855}
  • Loading branch information
ben authored and Commit bot committed Feb 25, 2015
1 parent c094da9 commit 726eb05
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 1 deletion.
15 changes: 15 additions & 0 deletions include/v8.h
Original file line number Diff line number Diff line change
Expand Up @@ -2617,13 +2617,28 @@ 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.
* This means interceptors in the prototype chain are not called.
*/
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();

Expand Down
40 changes: 40 additions & 0 deletions src/api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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()",
Expand All @@ -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.
Expand Down
26 changes: 25 additions & 1 deletion test/cctest/test-api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand Down

0 comments on commit 726eb05

Please sign in to comment.