Skip to content

Commit 56d7411

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 <verwaest@chromium.org> Reviewed-by: Adam Klein <adamk@chromium.org> Commit-Queue: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#55142} PR-URL: #22390 Fixes: #17480 Fixes: #17481 Refs: v8/v8@e1a7699 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 8dc1596 commit 56d7411

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.4',
32+
'v8_embedder_string': '-node.5',
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
@@ -5994,6 +5994,26 @@ enum class PropertyHandlerFlags {
59945994
};
59955995

59965996
struct NamedPropertyHandlerConfiguration {
5997+
NamedPropertyHandlerConfiguration(
5998+
GenericNamedPropertyGetterCallback getter,
5999+
GenericNamedPropertySetterCallback setter,
6000+
GenericNamedPropertyQueryCallback query,
6001+
GenericNamedPropertyDeleterCallback deleter,
6002+
GenericNamedPropertyEnumeratorCallback enumerator,
6003+
GenericNamedPropertyDefinerCallback definer,
6004+
GenericNamedPropertyDescriptorCallback descriptor,
6005+
Local<Value> data = Local<Value>(),
6006+
PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
6007+
: getter(getter),
6008+
setter(setter),
6009+
query(query),
6010+
deleter(deleter),
6011+
enumerator(enumerator),
6012+
definer(definer),
6013+
descriptor(descriptor),
6014+
data(data),
6015+
flags(flags) {}
6016+
59976017
NamedPropertyHandlerConfiguration(
59986018
/** Note: getter is required */
59996019
GenericNamedPropertyGetterCallback getter = 0,
@@ -6045,6 +6065,25 @@ struct NamedPropertyHandlerConfiguration {
60456065

60466066

60476067
struct IndexedPropertyHandlerConfiguration {
6068+
IndexedPropertyHandlerConfiguration(
6069+
IndexedPropertyGetterCallback getter,
6070+
IndexedPropertySetterCallback setter, IndexedPropertyQueryCallback query,
6071+
IndexedPropertyDeleterCallback deleter,
6072+
IndexedPropertyEnumeratorCallback enumerator,
6073+
IndexedPropertyDefinerCallback definer,
6074+
IndexedPropertyDescriptorCallback descriptor,
6075+
Local<Value> data = Local<Value>(),
6076+
PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
6077+
: getter(getter),
6078+
setter(setter),
6079+
query(query),
6080+
deleter(deleter),
6081+
enumerator(enumerator),
6082+
definer(definer),
6083+
descriptor(descriptor),
6084+
data(data),
6085+
flags(flags) {}
6086+
60486087
IndexedPropertyHandlerConfiguration(
60496088
/** Note: getter is required */
60506089
IndexedPropertyGetterCallback getter = 0,

deps/v8/src/api.cc

-4
Original file line numberDiff line numberDiff line change
@@ -1879,10 +1879,6 @@ static i::Handle<i::InterceptorInfo> CreateInterceptorInfo(
18791879
i::Isolate* isolate, Getter getter, Setter setter, Query query,
18801880
Descriptor descriptor, Deleter remover, Enumerator enumerator,
18811881
Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1882-
// Either intercept attributes or descriptor.
1883-
DCHECK(query == nullptr || descriptor == nullptr);
1884-
// Only use descriptor callback with definer callback.
1885-
DCHECK(query == nullptr || definer == nullptr);
18861882
auto obj = i::Handle<i::InterceptorInfo>::cast(
18871883
isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE, i::TENURED));
18881884
obj->set_flags(0);

deps/v8/src/objects.cc

+32-31
Original file line numberDiff line numberDiff line change
@@ -7817,41 +7817,42 @@ Maybe<bool> GetPropertyDescriptorWithInterceptor(LookupIterator* it,
78177817
}
78187818
}
78197819

7820-
if (it->state() == LookupIterator::INTERCEPTOR) {
7821-
Isolate* isolate = it->isolate();
7822-
Handle<InterceptorInfo> interceptor = it->GetInterceptor();
7823-
if (!interceptor->descriptor()->IsUndefined(isolate)) {
7824-
Handle<Object> result;
7825-
Handle<JSObject> holder = it->GetHolder<JSObject>();
7820+
if (it->state() != LookupIterator::INTERCEPTOR) return Just(false);
78267821

7827-
Handle<Object> receiver = it->GetReceiver();
7828-
if (!receiver->IsJSReceiver()) {
7829-
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
7830-
isolate, receiver, Object::ConvertReceiver(isolate, receiver),
7831-
Nothing<bool>());
7832-
}
7822+
Isolate* isolate = it->isolate();
7823+
Handle<InterceptorInfo> interceptor = it->GetInterceptor();
7824+
if (interceptor->descriptor()->IsUndefined(isolate)) return Just(false);
78337825

7834-
PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
7835-
*holder, kDontThrow);
7836-
if (it->IsElement()) {
7837-
result = args.CallIndexedDescriptor(interceptor, it->index());
7838-
} else {
7839-
result = args.CallNamedDescriptor(interceptor, it->name());
7840-
}
7841-
if (!result.is_null()) {
7842-
// Request successfully intercepted, try to set the property
7843-
// descriptor.
7844-
Utils::ApiCheck(
7845-
PropertyDescriptor::ToPropertyDescriptor(isolate, result, desc),
7846-
it->IsElement() ? "v8::IndexedPropertyDescriptorCallback"
7847-
: "v8::NamedPropertyDescriptorCallback",
7848-
"Invalid property descriptor.");
7826+
Handle<Object> result;
7827+
Handle<JSObject> holder = it->GetHolder<JSObject>();
78497828

7850-
return Just(true);
7851-
}
7852-
it->Next();
7853-
}
7829+
Handle<Object> receiver = it->GetReceiver();
7830+
if (!receiver->IsJSReceiver()) {
7831+
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
7832+
Object::ConvertReceiver(isolate, receiver),
7833+
Nothing<bool>());
7834+
}
7835+
7836+
PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
7837+
*holder, kDontThrow);
7838+
if (it->IsElement()) {
7839+
result = args.CallIndexedDescriptor(interceptor, it->index());
7840+
} else {
7841+
result = args.CallNamedDescriptor(interceptor, it->name());
78547842
}
7843+
if (!result.is_null()) {
7844+
// Request successfully intercepted, try to set the property
7845+
// descriptor.
7846+
Utils::ApiCheck(
7847+
PropertyDescriptor::ToPropertyDescriptor(isolate, result, desc),
7848+
it->IsElement() ? "v8::IndexedPropertyDescriptorCallback"
7849+
: "v8::NamedPropertyDescriptorCallback",
7850+
"Invalid property descriptor.");
7851+
7852+
return Just(true);
7853+
}
7854+
7855+
it->Next();
78557856
return Just(false);
78567857
}
78577858
} // 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)