Skip to content

Commit 726eb05

Browse files
benCommit bot
ben
authored and
Commit bot
committed
Add v8::Object::GetRealNamedPropertyAttributes()
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}
1 parent c094da9 commit 726eb05

File tree

3 files changed

+80
-1
lines changed

3 files changed

+80
-1
lines changed

include/v8.h

+15
Original file line numberDiff line numberDiff line change
@@ -2617,13 +2617,28 @@ class V8_EXPORT Object : public Value {
26172617
*/
26182618
Local<Value> GetRealNamedPropertyInPrototypeChain(Handle<String> key);
26192619

2620+
/**
2621+
* Gets the property attributes of a real property in the prototype chain,
2622+
* which can be None or any combination of ReadOnly, DontEnum and DontDelete.
2623+
* Interceptors in the prototype chain are not called.
2624+
*/
2625+
Maybe<PropertyAttribute> GetRealNamedPropertyAttributesInPrototypeChain(
2626+
Handle<String> key);
2627+
26202628
/**
26212629
* If result.IsEmpty() no real property was located on the object or
26222630
* in the prototype chain.
26232631
* This means interceptors in the prototype chain are not called.
26242632
*/
26252633
Local<Value> GetRealNamedProperty(Handle<String> key);
26262634

2635+
/**
2636+
* Gets the property attributes of a real property which can be
2637+
* None or any combination of ReadOnly, DontEnum and DontDelete.
2638+
* Interceptors in the prototype chain are not called.
2639+
*/
2640+
Maybe<PropertyAttribute> GetRealNamedPropertyAttributes(Handle<String> key);
2641+
26272642
/** Tests for a named lookup interceptor.*/
26282643
bool HasNamedLookupInterceptor();
26292644

src/api.cc

+40
Original file line numberDiff line numberDiff line change
@@ -3756,6 +3756,14 @@ static Local<Value> GetPropertyByLookup(i::LookupIterator* it) {
37563756
}
37573757

37583758

3759+
static Maybe<PropertyAttribute> GetPropertyAttributesByLookup(
3760+
i::LookupIterator* it) {
3761+
Maybe<PropertyAttributes> attr = i::JSReceiver::GetPropertyAttributes(it);
3762+
if (!it->IsFound()) return Maybe<PropertyAttribute>();
3763+
return Maybe<PropertyAttribute>(static_cast<PropertyAttribute>(attr.value));
3764+
}
3765+
3766+
37593767
Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
37603768
Handle<String> key) {
37613769
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
@@ -3774,6 +3782,24 @@ Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
37743782
}
37753783

37763784

3785+
Maybe<PropertyAttribute>
3786+
v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(Handle<String> key) {
3787+
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3788+
ON_BAILOUT(isolate,
3789+
"v8::Object::GetRealNamedPropertyAttributesInPrototypeChain()",
3790+
return Maybe<PropertyAttribute>());
3791+
ENTER_V8(isolate);
3792+
i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3793+
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
3794+
i::PrototypeIterator iter(isolate, self_obj);
3795+
if (iter.IsAtEnd()) return Maybe<PropertyAttribute>();
3796+
i::Handle<i::Object> proto = i::PrototypeIterator::GetCurrent(iter);
3797+
i::LookupIterator it(self_obj, key_obj, i::Handle<i::JSReceiver>::cast(proto),
3798+
i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
3799+
return GetPropertyAttributesByLookup(&it);
3800+
}
3801+
3802+
37773803
Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
37783804
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
37793805
ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
@@ -3787,6 +3813,20 @@ Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
37873813
}
37883814

37893815

3816+
Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
3817+
Handle<String> key) {
3818+
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3819+
ON_BAILOUT(isolate, "v8::Object::GetRealNamedPropertyAttributes()",
3820+
return Maybe<PropertyAttribute>());
3821+
ENTER_V8(isolate);
3822+
i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3823+
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
3824+
i::LookupIterator it(self_obj, key_obj,
3825+
i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
3826+
return GetPropertyAttributesByLookup(&it);
3827+
}
3828+
3829+
37903830
// Turns on access checks by copying the map and setting the check flag.
37913831
// Because the object gets a new map, existing inline cache caching
37923832
// the old map of this object will fail.

test/cctest/test-api.cc

+25-1
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,15 @@ using ::v8::FunctionTemplate;
6161
using ::v8::Handle;
6262
using ::v8::HandleScope;
6363
using ::v8::Local;
64-
using ::v8::Name;
64+
using ::v8::Maybe;
6565
using ::v8::Message;
6666
using ::v8::MessageCallback;
67+
using ::v8::Name;
68+
using ::v8::None;
6769
using ::v8::Object;
6870
using ::v8::ObjectTemplate;
6971
using ::v8::Persistent;
72+
using ::v8::PropertyAttribute;
7073
using ::v8::Script;
7174
using ::v8::StackTrace;
7275
using ::v8::String;
@@ -10869,16 +10872,32 @@ THREADED_TEST(VariousGetPropertiesAndThrowingCallbacks) {
1086910872
try_catch.Reset();
1087010873
CHECK(result.IsEmpty());
1087110874

10875+
Maybe<PropertyAttribute> attr =
10876+
instance->GetRealNamedPropertyAttributes(v8_str("f"));
10877+
CHECK(!try_catch.HasCaught());
10878+
CHECK(attr.has_value);
10879+
CHECK_EQ(attr.value, None);
10880+
1087210881
result = another->GetRealNamedProperty(v8_str("f"));
1087310882
CHECK(try_catch.HasCaught());
1087410883
try_catch.Reset();
1087510884
CHECK(result.IsEmpty());
1087610885

10886+
attr = another->GetRealNamedPropertyAttributes(v8_str("f"));
10887+
CHECK(!try_catch.HasCaught());
10888+
CHECK(attr.has_value);
10889+
CHECK_EQ(attr.value, None);
10890+
1087710891
result = another->GetRealNamedPropertyInPrototypeChain(v8_str("f"));
1087810892
CHECK(try_catch.HasCaught());
1087910893
try_catch.Reset();
1088010894
CHECK(result.IsEmpty());
1088110895

10896+
attr = another->GetRealNamedPropertyAttributesInPrototypeChain(v8_str("f"));
10897+
CHECK(!try_catch.HasCaught());
10898+
CHECK(attr.has_value);
10899+
CHECK_EQ(attr.value, None);
10900+
1088210901
result = another->Get(v8_str("f"));
1088310902
CHECK(try_catch.HasCaught());
1088410903
try_catch.Reset();
@@ -10889,6 +10908,11 @@ THREADED_TEST(VariousGetPropertiesAndThrowingCallbacks) {
1088910908
try_catch.Reset();
1089010909
CHECK(result.IsEmpty());
1089110910

10911+
attr = with_js_getter->GetRealNamedPropertyAttributes(v8_str("f"));
10912+
CHECK(!try_catch.HasCaught());
10913+
CHECK(attr.has_value);
10914+
CHECK_EQ(attr.value, None);
10915+
1089210916
result = with_js_getter->Get(v8_str("f"));
1089310917
CHECK(try_catch.HasCaught());
1089410918
try_catch.Reset();

0 commit comments

Comments
 (0)