Skip to content

Commit 221ce6c

Browse files
camillobrunitargos
authored andcommitted
deps: cherry-pick e1a7699 from upstream V8
Original commit message: [api][runtime] Support all-in ctors of {Named,Indexed}PropertyHandlerConfiguration - Explicitly allows construction of {Named,Indexed}PropertyHandlerConfiguration with all the members filled. Bug: v8:7612 Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng Change-Id: I426ea33846b5dbf2b3482c722c963a6e4b0abded Reviewed-on: https://chromium-review.googlesource.com/1163882 Reviewed-by: Toon Verwaest <[email protected]> Reviewed-by: Adam Klein <[email protected]> Commit-Queue: Camillo Bruni <[email protected]> Cr-Commit-Position: refs/heads/master@{#55142} PR-URL: #22390 Fixes: #17480 Fixes: #17481 Refs: v8/v8@e1a7699 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 0fde4e9 commit 221ce6c

File tree

5 files changed

+248
-36
lines changed

5 files changed

+248
-36
lines changed

common.gypi

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
# Reset this number to 0 on major V8 upgrades.
3131
# Increment by one for each non-official patch applied to deps/v8.
32-
'v8_embedder_string': '-node.16',
32+
'v8_embedder_string': '-node.17',
3333

3434
# Enable disassembler for `--print-code` v8 options
3535
'v8_enable_disassembler': 1,

deps/v8/include/v8.h

+39
Original file line numberDiff line numberDiff line change
@@ -5782,6 +5782,26 @@ enum class PropertyHandlerFlags {
57825782
};
57835783

57845784
struct NamedPropertyHandlerConfiguration {
5785+
NamedPropertyHandlerConfiguration(
5786+
GenericNamedPropertyGetterCallback getter,
5787+
GenericNamedPropertySetterCallback setter,
5788+
GenericNamedPropertyQueryCallback query,
5789+
GenericNamedPropertyDeleterCallback deleter,
5790+
GenericNamedPropertyEnumeratorCallback enumerator,
5791+
GenericNamedPropertyDefinerCallback definer,
5792+
GenericNamedPropertyDescriptorCallback descriptor,
5793+
Local<Value> data = Local<Value>(),
5794+
PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
5795+
: getter(getter),
5796+
setter(setter),
5797+
query(query),
5798+
deleter(deleter),
5799+
enumerator(enumerator),
5800+
definer(definer),
5801+
descriptor(descriptor),
5802+
data(data),
5803+
flags(flags) {}
5804+
57855805
NamedPropertyHandlerConfiguration(
57865806
/** Note: getter is required */
57875807
GenericNamedPropertyGetterCallback getter = 0,
@@ -5833,6 +5853,25 @@ struct NamedPropertyHandlerConfiguration {
58335853

58345854

58355855
struct IndexedPropertyHandlerConfiguration {
5856+
IndexedPropertyHandlerConfiguration(
5857+
IndexedPropertyGetterCallback getter,
5858+
IndexedPropertySetterCallback setter, IndexedPropertyQueryCallback query,
5859+
IndexedPropertyDeleterCallback deleter,
5860+
IndexedPropertyEnumeratorCallback enumerator,
5861+
IndexedPropertyDefinerCallback definer,
5862+
IndexedPropertyDescriptorCallback descriptor,
5863+
Local<Value> data = Local<Value>(),
5864+
PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
5865+
: getter(getter),
5866+
setter(setter),
5867+
query(query),
5868+
deleter(deleter),
5869+
enumerator(enumerator),
5870+
definer(definer),
5871+
descriptor(descriptor),
5872+
data(data),
5873+
flags(flags) {}
5874+
58365875
IndexedPropertyHandlerConfiguration(
58375876
/** Note: getter is required */
58385877
IndexedPropertyGetterCallback getter = 0,

deps/v8/src/api.cc

-4
Original file line numberDiff line numberDiff line change
@@ -1803,10 +1803,6 @@ static i::Handle<i::InterceptorInfo> CreateInterceptorInfo(
18031803
i::Isolate* isolate, Getter getter, Setter setter, Query query,
18041804
Descriptor descriptor, Deleter remover, Enumerator enumerator,
18051805
Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1806-
// Either intercept attributes or descriptor.
1807-
DCHECK(query == nullptr || descriptor == nullptr);
1808-
// Only use descriptor callback with definer callback.
1809-
DCHECK(query == nullptr || definer == nullptr);
18101806
auto obj = i::Handle<i::InterceptorInfo>::cast(
18111807
isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE, i::TENURED));
18121808
obj->set_flags(0);

deps/v8/src/objects.cc

+32-31
Original file line numberDiff line numberDiff line change
@@ -7672,41 +7672,42 @@ Maybe<bool> GetPropertyDescriptorWithInterceptor(LookupIterator* it,
76727672
}
76737673
}
76747674

7675-
if (it->state() == LookupIterator::INTERCEPTOR) {
7676-
Isolate* isolate = it->isolate();
7677-
Handle<InterceptorInfo> interceptor = it->GetInterceptor();
7678-
if (!interceptor->descriptor()->IsUndefined(isolate)) {
7679-
Handle<Object> result;
7680-
Handle<JSObject> holder = it->GetHolder<JSObject>();
7675+
if (it->state() != LookupIterator::INTERCEPTOR) return Just(false);
76817676

7682-
Handle<Object> receiver = it->GetReceiver();
7683-
if (!receiver->IsJSReceiver()) {
7684-
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
7685-
isolate, receiver, Object::ConvertReceiver(isolate, receiver),
7686-
Nothing<bool>());
7687-
}
7677+
Isolate* isolate = it->isolate();
7678+
Handle<InterceptorInfo> interceptor = it->GetInterceptor();
7679+
if (interceptor->descriptor()->IsUndefined(isolate)) return Just(false);
76887680

7689-
PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
7690-
*holder, kDontThrow);
7691-
if (it->IsElement()) {
7692-
result = args.CallIndexedDescriptor(interceptor, it->index());
7693-
} else {
7694-
result = args.CallNamedDescriptor(interceptor, it->name());
7695-
}
7696-
if (!result.is_null()) {
7697-
// Request successfully intercepted, try to set the property
7698-
// descriptor.
7699-
Utils::ApiCheck(
7700-
PropertyDescriptor::ToPropertyDescriptor(isolate, result, desc),
7701-
it->IsElement() ? "v8::IndexedPropertyDescriptorCallback"
7702-
: "v8::NamedPropertyDescriptorCallback",
7703-
"Invalid property descriptor.");
7681+
Handle<Object> result;
7682+
Handle<JSObject> holder = it->GetHolder<JSObject>();
77047683

7705-
return Just(true);
7706-
}
7707-
it->Next();
7708-
}
7684+
Handle<Object> receiver = it->GetReceiver();
7685+
if (!receiver->IsJSReceiver()) {
7686+
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
7687+
Object::ConvertReceiver(isolate, receiver),
7688+
Nothing<bool>());
7689+
}
7690+
7691+
PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
7692+
*holder, kDontThrow);
7693+
if (it->IsElement()) {
7694+
result = args.CallIndexedDescriptor(interceptor, it->index());
7695+
} else {
7696+
result = args.CallNamedDescriptor(interceptor, it->name());
77097697
}
7698+
if (!result.is_null()) {
7699+
// Request successfully intercepted, try to set the property
7700+
// descriptor.
7701+
Utils::ApiCheck(
7702+
PropertyDescriptor::ToPropertyDescriptor(isolate, result, desc),
7703+
it->IsElement() ? "v8::IndexedPropertyDescriptorCallback"
7704+
: "v8::NamedPropertyDescriptorCallback",
7705+
"Invalid property descriptor.");
7706+
7707+
return Just(true);
7708+
}
7709+
7710+
it->Next();
77107711
return Just(false);
77117712
}
77127713
} // namespace

deps/v8/test/unittests/api/interceptor-unittest.cc

+176
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,180 @@ TEST_F(InterceptorTest, FreezeApiObjectWithInterceptor) {
2929
}
3030

3131
} // namespace
32+
33+
namespace internal {
34+
namespace {
35+
36+
class InterceptorLoggingTest : public TestWithNativeContext {
37+
public:
38+
InterceptorLoggingTest() {}
39+
40+
static const int kTestIndex = 0;
41+
42+
static void NamedPropertyGetter(Local<v8::Name> name,
43+
const v8::PropertyCallbackInfo<Value>& info) {
44+
LogCallback(info, "named getter");
45+
}
46+
47+
static void NamedPropertySetter(Local<v8::Name> name, Local<v8::Value> value,
48+
const v8::PropertyCallbackInfo<Value>& info) {
49+
LogCallback(info, "named setter");
50+
}
51+
52+
static void NamedPropertyQuery(
53+
Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Integer>& info) {
54+
LogCallback(info, "named query");
55+
}
56+
57+
static void NamedPropertyDeleter(
58+
Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Boolean>& info) {
59+
LogCallback(info, "named deleter");
60+
}
61+
62+
static void NamedPropertyEnumerator(
63+
const v8::PropertyCallbackInfo<Array>& info) {
64+
LogCallback(info, "named enumerator");
65+
}
66+
67+
static void NamedPropertyDefiner(
68+
Local<v8::Name> name, const v8::PropertyDescriptor& desc,
69+
const v8::PropertyCallbackInfo<Value>& info) {
70+
LogCallback(info, "named definer");
71+
}
72+
73+
static void NamedPropertyDescriptor(
74+
Local<v8::Name> name, const v8::PropertyCallbackInfo<Value>& info) {
75+
LogCallback(info, "named descriptor");
76+
}
77+
78+
static void IndexedPropertyGetter(
79+
uint32_t index, const v8::PropertyCallbackInfo<Value>& info) {
80+
LogCallback(info, "indexed getter");
81+
}
82+
83+
static void IndexedPropertySetter(
84+
uint32_t index, Local<v8::Value> value,
85+
const v8::PropertyCallbackInfo<Value>& info) {
86+
LogCallback(info, "indexed setter");
87+
}
88+
89+
static void IndexedPropertyQuery(
90+
uint32_t index, const v8::PropertyCallbackInfo<v8::Integer>& info) {
91+
LogCallback(info, "indexed query");
92+
}
93+
94+
static void IndexedPropertyDeleter(
95+
uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info) {
96+
LogCallback(info, "indexed deleter");
97+
}
98+
99+
static void IndexedPropertyEnumerator(
100+
const v8::PropertyCallbackInfo<Array>& info) {
101+
LogCallback(info, "indexed enumerator");
102+
}
103+
104+
static void IndexedPropertyDefiner(
105+
uint32_t index, const v8::PropertyDescriptor& desc,
106+
const v8::PropertyCallbackInfo<Value>& info) {
107+
LogCallback(info, "indexed definer");
108+
}
109+
110+
static void IndexedPropertyDescriptor(
111+
uint32_t index, const v8::PropertyCallbackInfo<Value>& info) {
112+
LogCallback(info, "indexed descriptor");
113+
}
114+
115+
template <class T>
116+
static void LogCallback(const v8::PropertyCallbackInfo<T>& info,
117+
const char* callback_name) {
118+
InterceptorLoggingTest* test = reinterpret_cast<InterceptorLoggingTest*>(
119+
info.This()->GetAlignedPointerFromInternalField(kTestIndex));
120+
test->Log(callback_name);
121+
}
122+
123+
void Log(const char* callback_name) {
124+
if (log_is_empty_) {
125+
log_is_empty_ = false;
126+
} else {
127+
log_ << ", ";
128+
}
129+
log_ << callback_name;
130+
}
131+
132+
protected:
133+
void SetUp() override {
134+
// Set up the object that supports full interceptors.
135+
v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(v8_isolate());
136+
templ->SetInternalFieldCount(1);
137+
templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
138+
NamedPropertyGetter, NamedPropertySetter, NamedPropertyQuery,
139+
NamedPropertyDeleter, NamedPropertyEnumerator, NamedPropertyDefiner,
140+
NamedPropertyDescriptor));
141+
templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
142+
IndexedPropertyGetter, IndexedPropertySetter, IndexedPropertyQuery,
143+
IndexedPropertyDeleter, IndexedPropertyEnumerator,
144+
IndexedPropertyDefiner, IndexedPropertyDescriptor));
145+
v8::Local<v8::Object> instance =
146+
templ->NewInstance(context()).ToLocalChecked();
147+
instance->SetAlignedPointerInInternalField(kTestIndex, this);
148+
SetGlobalProperty("obj", instance);
149+
}
150+
151+
std::string Run(const char* script) {
152+
log_is_empty_ = true;
153+
log_.str(std::string());
154+
log_.clear();
155+
156+
RunJS(script);
157+
return log_.str();
158+
}
159+
160+
private:
161+
bool log_is_empty_ = false;
162+
std::stringstream log_;
163+
};
164+
165+
TEST_F(InterceptorLoggingTest, DispatchTest) {
166+
EXPECT_EQ(Run("for (var p in obj) {}"),
167+
"indexed enumerator, named enumerator");
168+
EXPECT_EQ(Run("Object.keys(obj)"), "indexed enumerator, named enumerator");
169+
170+
EXPECT_EQ(Run("obj.foo"), "named getter");
171+
EXPECT_EQ(Run("obj[42]"), "indexed getter");
172+
173+
EXPECT_EQ(Run("obj.foo = null"), "named setter");
174+
EXPECT_EQ(Run("obj[42] = null"), "indexed setter");
175+
176+
EXPECT_EQ(Run("Object.getOwnPropertyDescriptor(obj, 'foo')"),
177+
"named descriptor");
178+
179+
EXPECT_EQ(Run("Object.getOwnPropertyDescriptor(obj, 42)"),
180+
"indexed descriptor");
181+
182+
EXPECT_EQ(Run("Object.defineProperty(obj, 'foo', {value: 42})"),
183+
"named descriptor, named definer, named setter");
184+
EXPECT_EQ(Run("Object.defineProperty(obj, 'foo', {get(){} })"),
185+
"named descriptor, named definer");
186+
EXPECT_EQ(Run("Object.defineProperty(obj, 'foo', {set(value){}})"),
187+
"named descriptor, named definer");
188+
EXPECT_EQ(Run("Object.defineProperty(obj, 'foo', {get(){}, set(value){}})"),
189+
"named descriptor, named definer");
190+
191+
EXPECT_EQ(Run("Object.defineProperty(obj, 42, {value: 'foo'})"),
192+
"indexed descriptor, "
193+
// then attempt definer first and fallback to setter.
194+
"indexed definer, indexed setter");
195+
196+
EXPECT_EQ(Run("Object.prototype.propertyIsEnumerable.call(obj, 'a')"),
197+
"named query");
198+
EXPECT_EQ(Run("Object.prototype.propertyIsEnumerable.call(obj, 42)"),
199+
"indexed query");
200+
201+
EXPECT_EQ(Run("Object.prototype.hasOwnProperty.call(obj, 'a')"),
202+
"named query");
203+
// TODO(cbruni): Fix once hasOnwProperty is fixed (https://crbug.com/872628)
204+
EXPECT_EQ(Run("Object.prototype.hasOwnProperty.call(obj, '42')"), "");
205+
}
206+
} // namespace
207+
} // namespace internal
32208
} // namespace v8

0 commit comments

Comments
 (0)