Commit 8225465b authored by franzih's avatar franzih Committed by Commit bot

[api] Add documentation for PropertyQueryCallback.

Also add tests that document the behavior of the PropertyQueryCallback.

BUG=v8:5260

Review-Url: https://codereview.chromium.org/2286323002
Cr-Commit-Position: refs/heads/master@{#39090}
parent 79e685e2
......@@ -4556,11 +4556,26 @@ typedef void (*GenericNamedPropertySetterCallback)(
Local<Name> property, Local<Value> value,
const PropertyCallbackInfo<Value>& info);
/**
* Returns a non-empty handle if the interceptor intercepts the request.
* The result is an integer encoding property attributes (like v8::None,
* v8::DontEnum, etc.)
* Intercepts all requests that query the attributes of the
* property, e.g., getOwnPropertyDescriptor(), propertyIsEnumerable(), and
* defineProperty().
*
* Use `info.GetReturnValue().Set(value)` to set the property attributes. The
* value is an interger encoding a `v8::PropertyAttribute`.
*
* \param property The name of the property for which the request was
* intercepted.
* \param info Information about the intercepted request, such as
* isolate, receiver, return value, or whether running in `'use strict'` mode.
* See `PropertyCallbackInfo`.
*
* \note Some functions query the property attributes internally, even though
* they do not return the attributes. For example, `hasOwnProperty()` can
* trigger this interceptor depending on the state of the object.
*
* See also
* `ObjectTemplate::SetNamedPropertyHandler.`
*/
typedef void (*GenericNamedPropertyQueryCallback)(
Local<Name> property, const PropertyCallbackInfo<Integer>& info);
......
......@@ -346,6 +346,102 @@ void InterceptorHasOwnPropertyGetterGC(
} // namespace
int query_counter_int = 0;
namespace {
void QueryCallback(Local<Name> property,
const v8::PropertyCallbackInfo<v8::Integer>& info) {
query_counter_int++;
}
} // namespace
// Examples that show when the query callback is triggered.
THREADED_TEST(QueryInterceptor) {
v8::HandleScope scope(CcTest::isolate());
v8::Local<v8::FunctionTemplate> templ =
v8::FunctionTemplate::New(CcTest::isolate());
templ->InstanceTemplate()->SetHandler(
v8::NamedPropertyHandlerConfiguration(0, 0, QueryCallback));
LocalContext env;
env->Global()
->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local())
.ToLocalChecked()
->NewInstance(env.local())
.ToLocalChecked())
.FromJust();
CHECK_EQ(query_counter_int, 0);
v8::Local<Value> result =
v8_compile("Object.getOwnPropertyDescriptor(obj, 'x');")
->Run(env.local())
.ToLocalChecked();
CHECK_EQ(query_counter_int, 1);
CHECK_EQ(v8::PropertyAttribute::None,
static_cast<v8::PropertyAttribute>(
result->Int32Value(env.local()).FromJust()));
v8_compile("Object.defineProperty(obj, 'not_enum', {value: 17});")
->Run(env.local())
.ToLocalChecked();
CHECK_EQ(query_counter_int, 2);
v8_compile(
"Object.defineProperty(obj, 'enum', {value: 17, enumerable: true, "
"writable: true});")
->Run(env.local())
.ToLocalChecked();
CHECK_EQ(query_counter_int, 3);
CHECK(v8_compile("obj.propertyIsEnumerable('enum');")
->Run(env.local())
.ToLocalChecked()
->BooleanValue(env.local())
.FromJust());
CHECK_EQ(query_counter_int, 4);
CHECK(!v8_compile("obj.propertyIsEnumerable('not_enum');")
->Run(env.local())
.ToLocalChecked()
->BooleanValue(env.local())
.FromJust());
CHECK_EQ(query_counter_int, 5);
CHECK(v8_compile("obj.hasOwnProperty('enum');")
->Run(env.local())
.ToLocalChecked()
->BooleanValue(env.local())
.FromJust());
CHECK_EQ(query_counter_int, 5);
CHECK(v8_compile("obj.hasOwnProperty('not_enum');")
->Run(env.local())
.ToLocalChecked()
->BooleanValue(env.local())
.FromJust());
CHECK_EQ(query_counter_int, 5);
CHECK(!v8_compile("obj.hasOwnProperty('x');")
->Run(env.local())
.ToLocalChecked()
->BooleanValue(env.local())
.FromJust());
CHECK_EQ(query_counter_int, 6);
CHECK(!v8_compile("obj.propertyIsEnumerable('undef');")
->Run(env.local())
.ToLocalChecked()
->BooleanValue(env.local())
.FromJust());
CHECK_EQ(query_counter_int, 7);
v8_compile("Object.defineProperty(obj, 'enum', {value: 42});")
->Run(env.local())
.ToLocalChecked();
CHECK_EQ(query_counter_int, 8);
v8_compile("Object.isFrozen('obj.x');")->Run(env.local()).ToLocalChecked();
CHECK_EQ(query_counter_int, 8);
}
THREADED_TEST(InterceptorHasOwnProperty) {
LocalContext context;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment