summaryrefslogtreecommitdiff
path: root/deps
diff options
context:
space:
mode:
authorCamillo Bruni <cbruni@chromium.org>2018-08-18 13:41:51 -0400
committerMichaƫl Zasso <targos@protonmail.com>2018-09-07 21:07:07 +0200
commit56d7411be3c70a3e99cbc60aadee06bbc99a233e (patch)
tree9aae55644bf95295b09af879603ad500843e3586 /deps
parent8dc159658c97ff04dfc08ff5bfcd1a1a17b98430 (diff)
downloadandroid-node-v8-56d7411be3c70a3e99cbc60aadee06bbc99a233e.tar.gz
android-node-v8-56d7411be3c70a3e99cbc60aadee06bbc99a233e.tar.bz2
android-node-v8-56d7411be3c70a3e99cbc60aadee06bbc99a233e.zip
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: https://github.com/nodejs/node/pull/22390 Fixes: https://github.com/nodejs/node/issues/17480 Fixes: https://github.com/nodejs/node/issues/17481 Refs: https://github.com/v8/v8/commit/e1a76995ef311eb3ca66e12ef1941ed596034d59 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'deps')
-rw-r--r--deps/v8/include/v8.h39
-rw-r--r--deps/v8/src/api.cc4
-rw-r--r--deps/v8/src/objects.cc63
-rw-r--r--deps/v8/test/unittests/api/interceptor-unittest.cc176
4 files changed, 247 insertions, 35 deletions
diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h
index 23d5ba36db..20a65afcbc 100644
--- a/deps/v8/include/v8.h
+++ b/deps/v8/include/v8.h
@@ -5995,6 +5995,26 @@ enum class PropertyHandlerFlags {
struct NamedPropertyHandlerConfiguration {
NamedPropertyHandlerConfiguration(
+ GenericNamedPropertyGetterCallback getter,
+ GenericNamedPropertySetterCallback setter,
+ GenericNamedPropertyQueryCallback query,
+ GenericNamedPropertyDeleterCallback deleter,
+ GenericNamedPropertyEnumeratorCallback enumerator,
+ GenericNamedPropertyDefinerCallback definer,
+ GenericNamedPropertyDescriptorCallback descriptor,
+ Local<Value> data = Local<Value>(),
+ PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
+ : getter(getter),
+ setter(setter),
+ query(query),
+ deleter(deleter),
+ enumerator(enumerator),
+ definer(definer),
+ descriptor(descriptor),
+ data(data),
+ flags(flags) {}
+
+ NamedPropertyHandlerConfiguration(
/** Note: getter is required */
GenericNamedPropertyGetterCallback getter = 0,
GenericNamedPropertySetterCallback setter = 0,
@@ -6046,6 +6066,25 @@ struct NamedPropertyHandlerConfiguration {
struct IndexedPropertyHandlerConfiguration {
IndexedPropertyHandlerConfiguration(
+ IndexedPropertyGetterCallback getter,
+ IndexedPropertySetterCallback setter, IndexedPropertyQueryCallback query,
+ IndexedPropertyDeleterCallback deleter,
+ IndexedPropertyEnumeratorCallback enumerator,
+ IndexedPropertyDefinerCallback definer,
+ IndexedPropertyDescriptorCallback descriptor,
+ Local<Value> data = Local<Value>(),
+ PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
+ : getter(getter),
+ setter(setter),
+ query(query),
+ deleter(deleter),
+ enumerator(enumerator),
+ definer(definer),
+ descriptor(descriptor),
+ data(data),
+ flags(flags) {}
+
+ IndexedPropertyHandlerConfiguration(
/** Note: getter is required */
IndexedPropertyGetterCallback getter = 0,
IndexedPropertySetterCallback setter = 0,
diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc
index 7c569e3a9f..6155cbb325 100644
--- a/deps/v8/src/api.cc
+++ b/deps/v8/src/api.cc
@@ -1879,10 +1879,6 @@ static i::Handle<i::InterceptorInfo> CreateInterceptorInfo(
i::Isolate* isolate, Getter getter, Setter setter, Query query,
Descriptor descriptor, Deleter remover, Enumerator enumerator,
Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
- // Either intercept attributes or descriptor.
- DCHECK(query == nullptr || descriptor == nullptr);
- // Only use descriptor callback with definer callback.
- DCHECK(query == nullptr || definer == nullptr);
auto obj = i::Handle<i::InterceptorInfo>::cast(
isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE, i::TENURED));
obj->set_flags(0);
diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc
index 01421bacc4..0aac39d304 100644
--- a/deps/v8/src/objects.cc
+++ b/deps/v8/src/objects.cc
@@ -7817,41 +7817,42 @@ Maybe<bool> GetPropertyDescriptorWithInterceptor(LookupIterator* it,
}
}
- if (it->state() == LookupIterator::INTERCEPTOR) {
- Isolate* isolate = it->isolate();
- Handle<InterceptorInfo> interceptor = it->GetInterceptor();
- if (!interceptor->descriptor()->IsUndefined(isolate)) {
- Handle<Object> result;
- Handle<JSObject> holder = it->GetHolder<JSObject>();
+ if (it->state() != LookupIterator::INTERCEPTOR) return Just(false);
- Handle<Object> receiver = it->GetReceiver();
- if (!receiver->IsJSReceiver()) {
- ASSIGN_RETURN_ON_EXCEPTION_VALUE(
- isolate, receiver, Object::ConvertReceiver(isolate, receiver),
- Nothing<bool>());
- }
+ Isolate* isolate = it->isolate();
+ Handle<InterceptorInfo> interceptor = it->GetInterceptor();
+ if (interceptor->descriptor()->IsUndefined(isolate)) return Just(false);
- PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
- *holder, kDontThrow);
- if (it->IsElement()) {
- result = args.CallIndexedDescriptor(interceptor, it->index());
- } else {
- result = args.CallNamedDescriptor(interceptor, it->name());
- }
- if (!result.is_null()) {
- // Request successfully intercepted, try to set the property
- // descriptor.
- Utils::ApiCheck(
- PropertyDescriptor::ToPropertyDescriptor(isolate, result, desc),
- it->IsElement() ? "v8::IndexedPropertyDescriptorCallback"
- : "v8::NamedPropertyDescriptorCallback",
- "Invalid property descriptor.");
+ Handle<Object> result;
+ Handle<JSObject> holder = it->GetHolder<JSObject>();
- return Just(true);
- }
- it->Next();
- }
+ Handle<Object> receiver = it->GetReceiver();
+ if (!receiver->IsJSReceiver()) {
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
+ Object::ConvertReceiver(isolate, receiver),
+ Nothing<bool>());
+ }
+
+ PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
+ *holder, kDontThrow);
+ if (it->IsElement()) {
+ result = args.CallIndexedDescriptor(interceptor, it->index());
+ } else {
+ result = args.CallNamedDescriptor(interceptor, it->name());
}
+ if (!result.is_null()) {
+ // Request successfully intercepted, try to set the property
+ // descriptor.
+ Utils::ApiCheck(
+ PropertyDescriptor::ToPropertyDescriptor(isolate, result, desc),
+ it->IsElement() ? "v8::IndexedPropertyDescriptorCallback"
+ : "v8::NamedPropertyDescriptorCallback",
+ "Invalid property descriptor.");
+
+ return Just(true);
+ }
+
+ it->Next();
return Just(false);
}
} // namespace
diff --git a/deps/v8/test/unittests/api/interceptor-unittest.cc b/deps/v8/test/unittests/api/interceptor-unittest.cc
index 2f9f0e459e..b13384f18a 100644
--- a/deps/v8/test/unittests/api/interceptor-unittest.cc
+++ b/deps/v8/test/unittests/api/interceptor-unittest.cc
@@ -29,4 +29,180 @@ TEST_F(InterceptorTest, FreezeApiObjectWithInterceptor) {
}
} // namespace
+
+namespace internal {
+namespace {
+
+class InterceptorLoggingTest : public TestWithNativeContext {
+ public:
+ InterceptorLoggingTest() {}
+
+ static const int kTestIndex = 0;
+
+ static void NamedPropertyGetter(Local<v8::Name> name,
+ const v8::PropertyCallbackInfo<Value>& info) {
+ LogCallback(info, "named getter");
+ }
+
+ static void NamedPropertySetter(Local<v8::Name> name, Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<Value>& info) {
+ LogCallback(info, "named setter");
+ }
+
+ static void NamedPropertyQuery(
+ Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Integer>& info) {
+ LogCallback(info, "named query");
+ }
+
+ static void NamedPropertyDeleter(
+ Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Boolean>& info) {
+ LogCallback(info, "named deleter");
+ }
+
+ static void NamedPropertyEnumerator(
+ const v8::PropertyCallbackInfo<Array>& info) {
+ LogCallback(info, "named enumerator");
+ }
+
+ static void NamedPropertyDefiner(
+ Local<v8::Name> name, const v8::PropertyDescriptor& desc,
+ const v8::PropertyCallbackInfo<Value>& info) {
+ LogCallback(info, "named definer");
+ }
+
+ static void NamedPropertyDescriptor(
+ Local<v8::Name> name, const v8::PropertyCallbackInfo<Value>& info) {
+ LogCallback(info, "named descriptor");
+ }
+
+ static void IndexedPropertyGetter(
+ uint32_t index, const v8::PropertyCallbackInfo<Value>& info) {
+ LogCallback(info, "indexed getter");
+ }
+
+ static void IndexedPropertySetter(
+ uint32_t index, Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<Value>& info) {
+ LogCallback(info, "indexed setter");
+ }
+
+ static void IndexedPropertyQuery(
+ uint32_t index, const v8::PropertyCallbackInfo<v8::Integer>& info) {
+ LogCallback(info, "indexed query");
+ }
+
+ static void IndexedPropertyDeleter(
+ uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info) {
+ LogCallback(info, "indexed deleter");
+ }
+
+ static void IndexedPropertyEnumerator(
+ const v8::PropertyCallbackInfo<Array>& info) {
+ LogCallback(info, "indexed enumerator");
+ }
+
+ static void IndexedPropertyDefiner(
+ uint32_t index, const v8::PropertyDescriptor& desc,
+ const v8::PropertyCallbackInfo<Value>& info) {
+ LogCallback(info, "indexed definer");
+ }
+
+ static void IndexedPropertyDescriptor(
+ uint32_t index, const v8::PropertyCallbackInfo<Value>& info) {
+ LogCallback(info, "indexed descriptor");
+ }
+
+ template <class T>
+ static void LogCallback(const v8::PropertyCallbackInfo<T>& info,
+ const char* callback_name) {
+ InterceptorLoggingTest* test = reinterpret_cast<InterceptorLoggingTest*>(
+ info.This()->GetAlignedPointerFromInternalField(kTestIndex));
+ test->Log(callback_name);
+ }
+
+ void Log(const char* callback_name) {
+ if (log_is_empty_) {
+ log_is_empty_ = false;
+ } else {
+ log_ << ", ";
+ }
+ log_ << callback_name;
+ }
+
+ protected:
+ void SetUp() override {
+ // Set up the object that supports full interceptors.
+ v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(v8_isolate());
+ templ->SetInternalFieldCount(1);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ NamedPropertyGetter, NamedPropertySetter, NamedPropertyQuery,
+ NamedPropertyDeleter, NamedPropertyEnumerator, NamedPropertyDefiner,
+ NamedPropertyDescriptor));
+ templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+ IndexedPropertyGetter, IndexedPropertySetter, IndexedPropertyQuery,
+ IndexedPropertyDeleter, IndexedPropertyEnumerator,
+ IndexedPropertyDefiner, IndexedPropertyDescriptor));
+ v8::Local<v8::Object> instance =
+ templ->NewInstance(context()).ToLocalChecked();
+ instance->SetAlignedPointerInInternalField(kTestIndex, this);
+ SetGlobalProperty("obj", instance);
+ }
+
+ std::string Run(const char* script) {
+ log_is_empty_ = true;
+ log_.str(std::string());
+ log_.clear();
+
+ RunJS(script);
+ return log_.str();
+ }
+
+ private:
+ bool log_is_empty_ = false;
+ std::stringstream log_;
+};
+
+TEST_F(InterceptorLoggingTest, DispatchTest) {
+ EXPECT_EQ(Run("for (var p in obj) {}"),
+ "indexed enumerator, named enumerator");
+ EXPECT_EQ(Run("Object.keys(obj)"), "indexed enumerator, named enumerator");
+
+ EXPECT_EQ(Run("obj.foo"), "named getter");
+ EXPECT_EQ(Run("obj[42]"), "indexed getter");
+
+ EXPECT_EQ(Run("obj.foo = null"), "named setter");
+ EXPECT_EQ(Run("obj[42] = null"), "indexed setter");
+
+ EXPECT_EQ(Run("Object.getOwnPropertyDescriptor(obj, 'foo')"),
+ "named descriptor");
+
+ EXPECT_EQ(Run("Object.getOwnPropertyDescriptor(obj, 42)"),
+ "indexed descriptor");
+
+ EXPECT_EQ(Run("Object.defineProperty(obj, 'foo', {value: 42})"),
+ "named descriptor, named definer, named setter");
+ EXPECT_EQ(Run("Object.defineProperty(obj, 'foo', {get(){} })"),
+ "named descriptor, named definer");
+ EXPECT_EQ(Run("Object.defineProperty(obj, 'foo', {set(value){}})"),
+ "named descriptor, named definer");
+ EXPECT_EQ(Run("Object.defineProperty(obj, 'foo', {get(){}, set(value){}})"),
+ "named descriptor, named definer");
+
+ EXPECT_EQ(Run("Object.defineProperty(obj, 42, {value: 'foo'})"),
+ "indexed descriptor, "
+ // then attempt definer first and fallback to setter.
+ "indexed definer, indexed setter");
+
+ EXPECT_EQ(Run("Object.prototype.propertyIsEnumerable.call(obj, 'a')"),
+ "named query");
+ EXPECT_EQ(Run("Object.prototype.propertyIsEnumerable.call(obj, 42)"),
+ "indexed query");
+
+ EXPECT_EQ(Run("Object.prototype.hasOwnProperty.call(obj, 'a')"),
+ "named query");
+ // TODO(cbruni): Fix once hasOnwProperty is fixed (https://crbug.com/872628)
+ EXPECT_EQ(Run("Object.prototype.hasOwnProperty.call(obj, '42')"), "");
+}
+} // namespace
+} // namespace internal
} // namespace v8