[VM/Service] Add private _getImplementationFields procedure
TEST=CI
Change-Id: I4e4871ac4df74cb4daca7ef42a66489b2afbdc64
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/270260
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Derek Xu <derekx@google.com>
diff --git a/pkg/vm_service/test/get_implementation_fields_rpc_test.dart b/pkg/vm_service/test/get_implementation_fields_rpc_test.dart
new file mode 100644
index 0000000..e7b719f
--- /dev/null
+++ b/pkg/vm_service/test/get_implementation_fields_rpc_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+import 'package:vm_service/vm_service.dart';
+
+import 'common/test_helper.dart';
+
+Future<Response> getImplementationFields(
+ VmService service, String isolateId, String objectId) async {
+ return await service.callMethod("_getImplementationFields",
+ isolateId: isolateId, args: {"objectId": objectId});
+}
+
+var tests = <IsolateTest>[
+ // A null object.
+ (VmService service, IsolateRef isolateRef) async {
+ final isolateId = isolateRef.id!;
+ final objectId = 'objects/null';
+ final result = await getImplementationFields(service, isolateId, objectId);
+ expect(result.json!["type"]!, "ImplementationFields");
+ expect(result.json!["fields"]!, isEmpty);
+ },
+];
+
+main([args = const <String>[]]) async =>
+ runIsolateTests(args, tests, 'get_implementation_fields_rpc_test.dart');
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index e9b7956..6138ecb 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -217,7 +217,13 @@
/* with an object id is printed. If ref is false the object is fully */ \
/* printed. */ \
virtual void PrintJSONImpl(JSONStream* stream, bool ref) const; \
- virtual const char* JSONType() const { return "" #object; }
+ /* Prints JSON objects that describe the implementation-level fields of */ \
+ /* the current Object to |jsarr_fields|. */ \
+ virtual void PrintImplementationFieldsImpl(const JSONArray& jsarr_fields) \
+ const; \
+ virtual const char* JSONType() const { \
+ return "" #object; \
+ }
#else
#define OBJECT_SERVICE_SUPPORT(object) protected: /* NOLINT */
#endif // !PRODUCT
@@ -350,6 +356,9 @@
#ifndef PRODUCT
void PrintJSON(JSONStream* stream, bool ref = true) const;
virtual void PrintJSONImpl(JSONStream* stream, bool ref) const;
+ void PrintImplementationFields(JSONStream* stream) const;
+ virtual void PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const;
virtual const char* JSONType() const { return IsNull() ? "null" : "Object"; }
#endif
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 65fc7a0..14c7556 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -74,6 +74,20 @@
}
}
+void Object::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {
+ UNREACHABLE();
+}
+
+void Object::PrintImplementationFields(JSONStream* stream) const {
+ JSONObject jsobj(stream);
+ jsobj.AddProperty("type", "ImplementationFields");
+ JSONArray jsarr_fields(&jsobj, "fields");
+ if (!IsNull()) {
+ PrintImplementationFieldsImpl(jsarr_fields);
+ }
+}
+
void Class::PrintJSONImpl(JSONStream* stream, bool ref) const {
Isolate* isolate = Isolate::Current();
JSONObject jsobj(stream);
@@ -180,6 +194,9 @@
}
}
+void Class::PrintImplementationFieldsImpl(const JSONArray& jsarr_fields) const {
+}
+
void TypeParameters::PrintJSONImpl(JSONStream* stream, bool ref) const {
// Consider making this type public if we decide to expose TypeParameters
// through the protocol.
@@ -191,6 +208,9 @@
jsobj.AddProperty("defaults", TypeArguments::Handle(defaults()));
}
+void TypeParameters::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void TypeArguments::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
// The index in the canonical_type_arguments table cannot be used as part of
@@ -240,10 +260,16 @@
}
}
+void TypeArguments::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void PatchClass::PrintJSONImpl(JSONStream* stream, bool ref) const {
Object::PrintJSONImpl(stream, ref);
}
+void PatchClass::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Function::AddFunctionServiceId(const JSONObject& jsobj) const {
Class& cls = Class::Handle(Owner());
// Special kinds of functions use indices in their respective lists.
@@ -388,10 +414,16 @@
}
}
+void Function::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void FfiTrampolineData::PrintJSONImpl(JSONStream* stream, bool ref) const {
Object::PrintJSONImpl(stream, ref);
}
+void FfiTrampolineData::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Field::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
Class& cls = Class::Handle(Owner());
@@ -457,6 +489,9 @@
}
}
+void Field::PrintImplementationFieldsImpl(const JSONArray& jsarr_fields) const {
+}
+
// See also Dart_ScriptGetTokenInfo.
void Script::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
@@ -518,6 +553,9 @@
}
}
+void Script::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
static void PrintShowHideNamesToJSON(JSONObject* jsobj, const Namespace& ns) {
Array& arr = Array::Handle();
String& name = String::Handle();
@@ -666,18 +704,30 @@
}
}
+void Library::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void LibraryPrefix::PrintJSONImpl(JSONStream* stream, bool ref) const {
Object::PrintJSONImpl(stream, ref);
}
+void LibraryPrefix::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Namespace::PrintJSONImpl(JSONStream* stream, bool ref) const {
Object::PrintJSONImpl(stream, ref);
}
+void Namespace::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void KernelProgramInfo::PrintJSONImpl(JSONStream* stream, bool ref) const {
Object::PrintJSONImpl(stream, ref);
}
+void KernelProgramInfo::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Instructions::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Object", ref);
@@ -687,14 +737,23 @@
}
}
+void Instructions::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void InstructionsSection::PrintJSONImpl(JSONStream* stream, bool ref) const {
Object::PrintJSONImpl(stream, ref);
}
+void InstructionsSection::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void InstructionsTable::PrintJSONImpl(JSONStream* stream, bool ref) const {
Object::PrintJSONImpl(stream, ref);
}
+void InstructionsTable::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void WeakSerializationReference::PrintJSONImpl(JSONStream* stream,
bool ref) const {
JSONObject jsobj(stream);
@@ -705,6 +764,9 @@
jsobj.AddProperty("target", obj);
}
+void WeakSerializationReference::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void WeakArray::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Object", ref);
@@ -734,6 +796,9 @@
}
}
+void WeakArray::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void ObjectPool::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Object", ref);
@@ -773,6 +838,9 @@
}
}
+void ObjectPool::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void PcDescriptors::PrintToJSONObject(JSONObject* jsobj, bool ref) const {
AddCommonObjectProperties(jsobj, "Object", ref);
// TODO(johnmccutchan): Generate a stable id. PcDescriptors hang off a Code
@@ -799,14 +867,23 @@
PrintToJSONObject(&jsobj, ref);
}
+void PcDescriptors::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void CodeSourceMap::PrintJSONImpl(JSONStream* stream, bool ref) const {
Object::PrintJSONImpl(stream, ref);
}
+void CodeSourceMap::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void CompressedStackMaps::PrintJSONImpl(JSONStream* stream, bool ref) const {
Object::PrintJSONImpl(stream, ref);
}
+void CompressedStackMaps::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void LocalVarDescriptors::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Object", ref);
@@ -833,10 +910,16 @@
}
}
+void LocalVarDescriptors::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void ExceptionHandlers::PrintJSONImpl(JSONStream* stream, bool ref) const {
Object::PrintJSONImpl(stream, ref);
}
+void ExceptionHandlers::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void SingleTargetCache::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Object", ref);
@@ -849,6 +932,9 @@
jsobj.AddProperty("_upperLimit", upper_limit());
}
+void SingleTargetCache::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void UnlinkedCall::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Object", ref);
@@ -861,6 +947,9 @@
Array::Handle(arguments_descriptor()));
}
+void UnlinkedCall::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void MonomorphicSmiableCall::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Object", ref);
@@ -871,10 +960,18 @@
}
}
+void MonomorphicSmiableCall::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void CallSiteData::PrintJSONImpl(JSONStream* stream, bool ref) const {
UNREACHABLE();
}
+void CallSiteData::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {
+ UNREACHABLE();
+}
+
void ICData::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Object", ref);
@@ -916,6 +1013,9 @@
}
}
+void ICData::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Code::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Code", ref);
@@ -978,6 +1078,8 @@
PrintJSONInlineIntervals(&jsobj);
}
+void Code::PrintImplementationFieldsImpl(const JSONArray& jsarr_fields) const {}
+
void Context::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
// TODO(turnidge): Should the user level type for Context be Context
@@ -1005,10 +1107,16 @@
}
}
+void Context::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void ContextScope::PrintJSONImpl(JSONStream* stream, bool ref) const {
Object::PrintJSONImpl(stream, ref);
}
+void ContextScope::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Sentinel::PrintJSONImpl(JSONStream* stream, bool ref) const {
// Handle certain special sentinel values.
if (ptr() == Object::sentinel().ptr()) {
@@ -1034,6 +1142,9 @@
Object::PrintJSONImpl(stream, ref);
}
+void Sentinel::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void MegamorphicCache::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Object", ref);
@@ -1048,6 +1159,9 @@
Object::Handle(arguments_descriptor()));
}
+void MegamorphicCache::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void SubtypeTestCache::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Object", ref);
@@ -1058,6 +1172,9 @@
jsobj.AddProperty("_cache", Array::Handle(cache()));
}
+void SubtypeTestCache::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void LoadingUnit::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Object", ref);
@@ -1072,10 +1189,17 @@
jsobj.AddProperty("_loadOutstanding", load_outstanding());
}
+void LoadingUnit::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Error::PrintJSONImpl(JSONStream* stream, bool ref) const {
UNREACHABLE();
}
+void Error::PrintImplementationFieldsImpl(const JSONArray& jsarr_fields) const {
+ UNREACHABLE();
+}
+
void ApiError::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Error", ref);
@@ -1084,6 +1208,9 @@
jsobj.AddProperty("message", ToErrorCString());
}
+void ApiError::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void LanguageError::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Error", ref);
@@ -1092,6 +1219,9 @@
jsobj.AddProperty("message", ToErrorCString());
}
+void LanguageError::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void UnhandledException::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Error", ref);
@@ -1108,6 +1238,9 @@
jsobj.AddProperty("stacktrace", instance);
}
+void UnhandledException::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void UnwindError::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Error", ref);
@@ -1117,6 +1250,9 @@
jsobj.AddProperty("_is_user_initiated", is_user_initiated());
}
+void UnwindError::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Instance::PrintSharedInstanceJSON(JSONObject* jsobj,
bool ref,
bool include_id) const {
@@ -1185,10 +1321,18 @@
jsobj.AddProperty("kind", "PlainInstance");
}
+void Instance::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void AbstractType::PrintJSONImpl(JSONStream* stream, bool ref) const {
UNREACHABLE();
}
+void AbstractType::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {
+ UNREACHABLE();
+}
+
void Type::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref, /*include_id=*/false);
@@ -1213,6 +1357,8 @@
}
}
+void Type::PrintImplementationFieldsImpl(const JSONArray& jsarr_fields) const {}
+
void FunctionType::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1251,6 +1397,9 @@
}
}
+void FunctionType::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void RecordType::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1283,6 +1432,9 @@
}
}
+void RecordType::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void TypeRef::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1296,6 +1448,9 @@
jsobj.AddProperty("targetType", AbstractType::Handle(type()));
}
+void TypeRef::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void TypeParameter::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1314,10 +1469,18 @@
jsobj.AddProperty("bound", upper_bound);
}
+void TypeParameter::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Number::PrintJSONImpl(JSONStream* stream, bool ref) const {
UNREACHABLE();
}
+void Number::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {
+ UNREACHABLE();
+}
+
void Integer::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1325,6 +1488,9 @@
jsobj.AddProperty("valueAsString", ToCString());
}
+void Integer::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Smi::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref, /*include_id=*/false);
@@ -1333,10 +1499,14 @@
jsobj.AddPropertyF("valueAsString", "%" Pd "", Value());
}
+void Smi::PrintImplementationFieldsImpl(const JSONArray& jsarr_fields) const {}
+
void Mint::PrintJSONImpl(JSONStream* stream, bool ref) const {
Integer::PrintJSONImpl(stream, ref);
}
+void Mint::PrintImplementationFieldsImpl(const JSONArray& jsarr_fields) const {}
+
void Double::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1344,6 +1514,9 @@
jsobj.AddProperty("valueAsString", ToCString());
}
+void Double::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void String::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1371,6 +1544,9 @@
jsobj.AddPropertyStr("valueAsString", *this, offset, count);
}
+void String::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Bool::PrintJSONImpl(JSONStream* stream, bool ref) const {
const char* str = ToCString();
JSONObject jsobj(stream);
@@ -1380,6 +1556,8 @@
jsobj.AddPropertyF("valueAsString", "%s", str);
}
+void Bool::PrintImplementationFieldsImpl(const JSONArray& jsarr_fields) const {}
+
void Array::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1409,6 +1587,9 @@
}
}
+void Array::PrintImplementationFieldsImpl(const JSONArray& jsarr_fields) const {
+}
+
void GrowableObjectArray::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1438,6 +1619,9 @@
}
}
+void GrowableObjectArray::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Map::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1475,6 +1659,8 @@
}
}
+void Map::PrintImplementationFieldsImpl(const JSONArray& jsarr_fields) const {}
+
void Set::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1509,6 +1695,8 @@
}
}
+void Set::PrintImplementationFieldsImpl(const JSONArray& jsarr_fields) const {}
+
void Float32x4::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1516,6 +1704,9 @@
jsobj.AddProperty("valueAsString", ToCString());
}
+void Float32x4::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Int32x4::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1523,6 +1714,9 @@
jsobj.AddProperty("valueAsString", ToCString());
}
+void Int32x4::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Float64x2::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1530,10 +1724,18 @@
jsobj.AddProperty("valueAsString", ToCString());
}
+void Float64x2::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void TypedDataBase::PrintJSONImpl(JSONStream* stream, bool ref) const {
UNREACHABLE();
}
+void TypedDataBase::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {
+ UNREACHABLE();
+}
+
void TypedData::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1564,10 +1766,16 @@
}
}
+void TypedData::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void TypedDataView::PrintJSONImpl(JSONStream* stream, bool ref) const {
Instance::PrintJSONImpl(stream, ref);
}
+void TypedDataView::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void ExternalTypedData::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1598,18 +1806,30 @@
}
}
+void ExternalTypedData::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Pointer::PrintJSONImpl(JSONStream* stream, bool ref) const {
Instance::PrintJSONImpl(stream, ref);
}
+void Pointer::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void DynamicLibrary::PrintJSONImpl(JSONStream* stream, bool ref) const {
Instance::PrintJSONImpl(stream, ref);
}
+void DynamicLibrary::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Capability::PrintJSONImpl(JSONStream* stream, bool ref) const {
Instance::PrintJSONImpl(stream, ref);
}
+void Capability::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void ReceivePort::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject obj(stream);
Instance::PrintSharedInstanceJSON(&obj, ref);
@@ -1622,18 +1842,30 @@
obj.AddProperty("allocationLocation", allocation_location_);
}
+void ReceivePort::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void SendPort::PrintJSONImpl(JSONStream* stream, bool ref) const {
Instance::PrintJSONImpl(stream, ref);
}
+void SendPort::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void TransferableTypedData::PrintJSONImpl(JSONStream* stream, bool ref) const {
Instance::PrintJSONImpl(stream, ref);
}
+void TransferableTypedData::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void ClosureData::PrintJSONImpl(JSONStream* stream, bool ref) const {
Object::PrintJSONImpl(stream, ref);
}
+void ClosureData::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Closure::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1653,6 +1885,9 @@
}
}
+void Closure::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void Record::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1685,6 +1920,9 @@
}
}
+void Record::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void StackTrace::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1692,6 +1930,9 @@
jsobj.AddProperty("valueAsString", ToCString());
}
+void StackTrace::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void RegExp::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1737,6 +1978,9 @@
}
}
+void RegExp::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void WeakProperty::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1751,6 +1995,9 @@
jsobj.AddProperty("propertyValue", value_handle);
}
+void WeakProperty::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void WeakReference::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1763,10 +2010,18 @@
jsobj.AddProperty("target", target_handle);
}
+void WeakReference::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void FinalizerBase::PrintJSONImpl(JSONStream* stream, bool ref) const {
UNREACHABLE();
}
+void FinalizerBase::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {
+ UNREACHABLE();
+}
+
void Finalizer::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1781,6 +2036,9 @@
// Not exposing entries.
}
+void Finalizer::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void NativeFinalizer::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1795,10 +2053,18 @@
// Not exposing entries.
}
+void NativeFinalizer::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void FinalizerEntry::PrintJSONImpl(JSONStream* stream, bool ref) const {
UNREACHABLE();
}
+void FinalizerEntry::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {
+ UNREACHABLE();
+}
+
void MirrorReference::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
PrintSharedInstanceJSON(&jsobj, ref);
@@ -1812,18 +2078,30 @@
jsobj.AddProperty("mirrorReferent", referent_handle);
}
+void MirrorReference::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const {
Instance::PrintJSONImpl(stream, ref);
}
+void UserTag::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void FutureOr::PrintJSONImpl(JSONStream* stream, bool ref) const {
Instance::PrintJSONImpl(stream, ref);
}
+void FutureOr::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
void SuspendState::PrintJSONImpl(JSONStream* stream, bool ref) const {
Instance::PrintJSONImpl(stream, ref);
}
+void SuspendState::PrintImplementationFieldsImpl(
+ const JSONArray& jsarr_fields) const {}
+
#endif
} // namespace dart
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 5e6a10e..2d69e6a 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -177,6 +177,7 @@
#define ISOLATE_GROUP_PARAMETER new IdParameter("isolateGroupId", true)
#define NO_ISOLATE_PARAMETER new NoSuchParameter("isolateId")
#define RUNNABLE_ISOLATE_PARAMETER new RunnableIsolateParameter("isolateId")
+#define OBJECT_PARAMETER new IdParameter("objectId", true)
class EnumListParameter : public MethodParameter {
public:
@@ -4987,6 +4988,42 @@
jsobj.AddProperty("bart", "simpson");
}
+// Returns |true| if a heap object with the specified ID was successfully found,
+// and |false| otherwise. If an object was found, it will be stored at address
+// |obj|.
+// This function should be used to handle shared logic between |GetObject| and
+// |GetImplementationFields|.
+static bool GetHeapObjectCommon(Thread* thread,
+ JSONStream* js,
+ const char* id,
+ Object* obj,
+ ObjectIdRing::LookupResult* lookup_result) {
+ *obj = LookupHeapObject(thread, id, lookup_result);
+ ASSERT(obj != nullptr);
+ ASSERT(lookup_result != nullptr);
+ if (obj->ptr() != Object::sentinel().ptr()) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ // If obj is a script from dart:* and doesn't have source loaded, try and
+ // load the source before sending the response.
+ if (obj->IsScript()) {
+ const Script& script = Script::Cast(*obj);
+ script.LookupSourceAndLineStarts(thread->zone());
+ if (!script.HasSource() && script.IsPartOfDartColonLibrary() &&
+ Service::HasDartLibraryKernelForSources()) {
+ const uint8_t* kernel_buffer = Service::dart_library_kernel();
+ const intptr_t kernel_buffer_len =
+ Service::dart_library_kernel_length();
+ script.LoadSourceFromKernel(kernel_buffer, kernel_buffer_len);
+ }
+ }
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ // We found a heap object for this id.
+ return true;
+ }
+
+ return false;
+}
+
static const MethodParameter* const get_object_params[] = {
RUNNABLE_ISOLATE_PARAMETER,
new UIntParameter("offset", false),
@@ -5018,25 +5055,9 @@
}
// Handle heap objects.
+ Object& obj = Object::Handle();
ObjectIdRing::LookupResult lookup_result;
- Object& obj = Object::Handle(LookupHeapObject(thread, id, &lookup_result));
- if (obj.ptr() != Object::sentinel().ptr()) {
-#if !defined(DART_PRECOMPILED_RUNTIME)
- // If obj is a script from dart:* and doesn't have source loaded, try and
- // load the source before sending the response.
- if (obj.IsScript()) {
- const Script& script = Script::Cast(obj);
- script.LookupSourceAndLineStarts(thread->zone());
- if (!script.HasSource() && script.IsPartOfDartColonLibrary() &&
- Service::HasDartLibraryKernelForSources()) {
- const uint8_t* kernel_buffer = Service::dart_library_kernel();
- const intptr_t kernel_buffer_len =
- Service::dart_library_kernel_length();
- script.LoadSourceFromKernel(kernel_buffer, kernel_buffer_len);
- }
- }
-#endif // !defined(DART_PRECOMPILED_RUNTIME)
- // We found a heap object for this id. Return it.
+ if (GetHeapObjectCommon(thread, js, id, &obj, &lookup_result)) {
obj.PrintJSON(js, false);
return;
} else if (lookup_result == ObjectIdRing::kCollected) {
@@ -5060,6 +5081,44 @@
PrintInvalidParamError(js, "objectId");
}
+static const MethodParameter* const get_implementation_fields_params[] = {
+ RUNNABLE_ISOLATE_PARAMETER,
+ OBJECT_PARAMETER,
+ nullptr,
+};
+
+static void GetImplementationFields(Thread* thread, JSONStream* js) {
+ const char* id = js->LookupParam("objectId");
+
+ // Handle heap objects.
+ Object& obj = Object::Handle();
+ ObjectIdRing::LookupResult lookup_result;
+ if (GetHeapObjectCommon(thread, js, id, &obj, &lookup_result)) {
+ obj.PrintImplementationFields(js);
+ return;
+ } else if (lookup_result == ObjectIdRing::kCollected) {
+ PrintSentinel(js, kCollectedSentinel);
+ return;
+ } else if (lookup_result == ObjectIdRing::kExpired) {
+ PrintSentinel(js, kExpiredSentinel);
+ return;
+ }
+
+ // Handle non-heap objects.
+ Breakpoint* bpt = LookupBreakpoint(thread->isolate(), id, &lookup_result);
+ if (bpt != nullptr) {
+ const JSONObject jsobj(js);
+ jsobj.AddProperty("type", "ImplementationFields");
+ JSONArray jsarr_fields(&jsobj, "fields");
+ return;
+ } else if (lookup_result == ObjectIdRing::kCollected) {
+ PrintSentinel(js, kCollectedSentinel);
+ return;
+ }
+
+ PrintInvalidParamError(js, "objectId");
+}
+
static const MethodParameter* const get_object_store_params[] = {
RUNNABLE_ISOLATE_PARAMETER,
NULL,
@@ -5815,6 +5874,8 @@
get_flag_list_params },
{ "_getHeapMap", GetHeapMap,
get_heap_map_params },
+ { "_getImplementationFields", GetImplementationFields,
+ get_implementation_fields_params },
{ "getInboundReferences", GetInboundReferences,
get_inbound_references_params },
{ "getInstances", GetInstances,