Commit ae04947a authored by Benedikt Meurer's avatar Benedikt Meurer Committed by V8 LUCI CQ

[inspector] Correctly report private accessor properties.

When calling `Runtime.getProperties` with `accessorPropertiesOnly` we
previously did not report any private fields at all, although it is
possible to define private accessors.

Bug: chromium:1296855
Change-Id: I18b84bfc81449d224738ba3de1f0c41c234025b2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3477112
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarKim-Anh Tran <kimanh@chromium.org>
Auto-Submit: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79210}
parent 418b5fc2
...@@ -440,6 +440,7 @@ Response InjectedScript::getProperties( ...@@ -440,6 +440,7 @@ Response InjectedScript::getProperties(
Response InjectedScript::getInternalAndPrivateProperties( Response InjectedScript::getInternalAndPrivateProperties(
v8::Local<v8::Value> value, const String16& groupName, v8::Local<v8::Value> value, const String16& groupName,
bool accessorPropertiesOnly,
std::unique_ptr<protocol::Array<InternalPropertyDescriptor>>* std::unique_ptr<protocol::Array<InternalPropertyDescriptor>>*
internalProperties, internalProperties,
std::unique_ptr<protocol::Array<PrivatePropertyDescriptor>>* std::unique_ptr<protocol::Array<PrivatePropertyDescriptor>>*
...@@ -453,27 +454,31 @@ Response InjectedScript::getInternalAndPrivateProperties( ...@@ -453,27 +454,31 @@ Response InjectedScript::getInternalAndPrivateProperties(
v8::Local<v8::Context> context = m_context->context(); v8::Local<v8::Context> context = m_context->context();
int sessionId = m_sessionId; int sessionId = m_sessionId;
std::vector<InternalPropertyMirror> internalPropertiesWrappers;
ValueMirror::getInternalProperties(m_context->context(), value_obj, if (!accessorPropertiesOnly) {
&internalPropertiesWrappers); std::vector<InternalPropertyMirror> internalPropertiesWrappers;
for (const auto& internalProperty : internalPropertiesWrappers) { ValueMirror::getInternalProperties(m_context->context(), value_obj,
std::unique_ptr<RemoteObject> remoteObject; &internalPropertiesWrappers);
Response response = internalProperty.value->buildRemoteObject( for (const auto& internalProperty : internalPropertiesWrappers) {
m_context->context(), WrapMode::kNoPreview, &remoteObject); std::unique_ptr<RemoteObject> remoteObject;
if (!response.IsSuccess()) return response; Response response = internalProperty.value->buildRemoteObject(
response = bindRemoteObjectIfNeeded(sessionId, context, m_context->context(), WrapMode::kNoPreview, &remoteObject);
internalProperty.value->v8Value(), if (!response.IsSuccess()) return response;
groupName, remoteObject.get()); response = bindRemoteObjectIfNeeded(sessionId, context,
if (!response.IsSuccess()) return response; internalProperty.value->v8Value(),
(*internalProperties) groupName, remoteObject.get());
->emplace_back(InternalPropertyDescriptor::create() if (!response.IsSuccess()) return response;
.setName(internalProperty.name) (*internalProperties)
.setValue(std::move(remoteObject)) ->emplace_back(InternalPropertyDescriptor::create()
.build()); .setName(internalProperty.name)
.setValue(std::move(remoteObject))
.build());
}
} }
std::vector<PrivatePropertyMirror> privatePropertyWrappers = std::vector<PrivatePropertyMirror> privatePropertyWrappers =
ValueMirror::getPrivateProperties(context, value_obj); ValueMirror::getPrivateProperties(context, value_obj,
accessorPropertiesOnly);
for (const auto& privateProperty : privatePropertyWrappers) { for (const auto& privateProperty : privatePropertyWrappers) {
std::unique_ptr<PrivatePropertyDescriptor> descriptor = std::unique_ptr<PrivatePropertyDescriptor> descriptor =
PrivatePropertyDescriptor::create() PrivatePropertyDescriptor::create()
......
...@@ -85,6 +85,7 @@ class InjectedScript final { ...@@ -85,6 +85,7 @@ class InjectedScript final {
Response getInternalAndPrivateProperties( Response getInternalAndPrivateProperties(
v8::Local<v8::Value>, const String16& groupName, v8::Local<v8::Value>, const String16& groupName,
bool accessorPropertiesOnly,
std::unique_ptr< std::unique_ptr<
protocol::Array<protocol::Runtime::InternalPropertyDescriptor>>* protocol::Array<protocol::Runtime::InternalPropertyDescriptor>>*
internalProperties, internalProperties,
......
...@@ -452,15 +452,14 @@ Response V8RuntimeAgentImpl::getProperties( ...@@ -452,15 +452,14 @@ Response V8RuntimeAgentImpl::getProperties(
: WrapMode::kNoPreview, : WrapMode::kNoPreview,
result, exceptionDetails); result, exceptionDetails);
if (!response.IsSuccess()) return response; if (!response.IsSuccess()) return response;
if (exceptionDetails->isJust() || accessorPropertiesOnly.fromMaybe(false)) if (exceptionDetails->isJust()) return Response::Success();
return Response::Success();
std::unique_ptr<protocol::Array<InternalPropertyDescriptor>> std::unique_ptr<protocol::Array<InternalPropertyDescriptor>>
internalPropertiesProtocolArray; internalPropertiesProtocolArray;
std::unique_ptr<protocol::Array<PrivatePropertyDescriptor>> std::unique_ptr<protocol::Array<PrivatePropertyDescriptor>>
privatePropertiesProtocolArray; privatePropertiesProtocolArray;
response = scope.injectedScript()->getInternalAndPrivateProperties( response = scope.injectedScript()->getInternalAndPrivateProperties(
object, scope.objectGroupName(), &internalPropertiesProtocolArray, object, scope.objectGroupName(), accessorPropertiesOnly.fromMaybe(false),
&privatePropertiesProtocolArray); &internalPropertiesProtocolArray, &privatePropertiesProtocolArray);
if (!response.IsSuccess()) return response; if (!response.IsSuccess()) return response;
if (!internalPropertiesProtocolArray->empty()) if (!internalPropertiesProtocolArray->empty())
*internalProperties = std::move(internalPropertiesProtocolArray); *internalProperties = std::move(internalPropertiesProtocolArray);
......
...@@ -893,7 +893,8 @@ void getPrivatePropertiesForPreview( ...@@ -893,7 +893,8 @@ void getPrivatePropertiesForPreview(
int* nameLimit, bool* overflow, int* nameLimit, bool* overflow,
protocol::Array<PropertyPreview>* privateProperties) { protocol::Array<PropertyPreview>* privateProperties) {
std::vector<PrivatePropertyMirror> mirrors = std::vector<PrivatePropertyMirror> mirrors =
ValueMirror::getPrivateProperties(context, object); ValueMirror::getPrivateProperties(context, object,
/* accessPropertiesOnly */ false);
for (auto& mirror : mirrors) { for (auto& mirror : mirrors) {
std::unique_ptr<PropertyPreview> propertyPreview; std::unique_ptr<PropertyPreview> propertyPreview;
if (mirror.value) { if (mirror.value) {
...@@ -1429,7 +1430,8 @@ void ValueMirror::getInternalProperties( ...@@ -1429,7 +1430,8 @@ void ValueMirror::getInternalProperties(
// static // static
std::vector<PrivatePropertyMirror> ValueMirror::getPrivateProperties( std::vector<PrivatePropertyMirror> ValueMirror::getPrivateProperties(
v8::Local<v8::Context> context, v8::Local<v8::Object> object) { v8::Local<v8::Context> context, v8::Local<v8::Object> object,
bool accessorPropertiesOnly) {
std::vector<PrivatePropertyMirror> mirrors; std::vector<PrivatePropertyMirror> mirrors;
v8::Isolate* isolate = context->GetIsolate(); v8::Isolate* isolate = context->GetIsolate();
v8::MicrotasksScope microtasksScope(isolate, v8::MicrotasksScope microtasksScope(isolate,
...@@ -1462,6 +1464,8 @@ std::vector<PrivatePropertyMirror> ValueMirror::getPrivateProperties( ...@@ -1462,6 +1464,8 @@ std::vector<PrivatePropertyMirror> ValueMirror::getPrivateProperties(
if (!setter->IsNull()) { if (!setter->IsNull()) {
setterMirror = ValueMirror::create(context, setter); setterMirror = ValueMirror::create(context, setter);
} }
} else if (accessorPropertiesOnly) {
continue;
} else { } else {
valueMirror = ValueMirror::create(context, value); valueMirror = ValueMirror::create(context, value);
} }
......
...@@ -81,7 +81,8 @@ class ValueMirror { ...@@ -81,7 +81,8 @@ class ValueMirror {
v8::Local<v8::Context> context, v8::Local<v8::Object> object, v8::Local<v8::Context> context, v8::Local<v8::Object> object,
std::vector<InternalPropertyMirror>* mirrors); std::vector<InternalPropertyMirror>* mirrors);
static std::vector<PrivatePropertyMirror> getPrivateProperties( static std::vector<PrivatePropertyMirror> getPrivateProperties(
v8::Local<v8::Context> context, v8::Local<v8::Object> object); v8::Local<v8::Context> context, v8::Local<v8::Object> object,
bool accessorPropertiesOnly);
}; };
protocol::Response toProtocolValue(v8::Local<v8::Context> context, protocol::Response toProtocolValue(v8::Local<v8::Context> context,
......
Test private class methods Test private class methods
Running test: testScopesPaused Running test: testScopesPaused
privateProperties on the base class instance private properties on the base class instance
[ [
[0] : { [0] : {
name : #inc name : #inc
...@@ -54,6 +54,42 @@ privateProperties on the base class instance ...@@ -54,6 +54,42 @@ privateProperties on the base class instance
} }
} }
] ]
private accessors properties on the base class instance
[
[0] : {
name : #writeOnly
set : {
className : Function
description : set #writeOnly(val) { this.#field = val; }
objectId : <objectId>
type : function
}
}
[1] : {
get : {
className : Function
description : get #readOnly() { return this.#field; }
objectId : <objectId>
type : function
}
name : #readOnly
}
[2] : {
get : {
className : Function
description : get #accessor() { return this.#field; }
objectId : <objectId>
type : function
}
name : #accessor
set : {
className : Function
description : set #accessor(val) { this.#field = val; }
objectId : <objectId>
type : function
}
}
]
Evaluating private methods Evaluating private methods
{ {
result : { result : {
......
...@@ -56,7 +56,15 @@ InspectorTest.runAsyncTestSuite([ ...@@ -56,7 +56,15 @@ InspectorTest.runAsyncTestSuite([
objectId: frame.this.objectId objectId: frame.this.objectId
}); });
InspectorTest.log('privateProperties on the base class instance'); InspectorTest.log('private properties on the base class instance');
InspectorTest.logMessage(result.privateProperties);
({ result } = await Protocol.Runtime.getProperties({
objectId: frame.this.objectId,
accessorPropertiesOnly: true,
}));
InspectorTest.log('private accessors properties on the base class instance');
InspectorTest.logMessage(result.privateProperties); InspectorTest.logMessage(result.privateProperties);
({ result } = await Protocol.Debugger.evaluateOnCallFrame({ ({ result } = await Protocol.Debugger.evaluateOnCallFrame({
......
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