125 lines
3.9 KiB
C
125 lines
3.9 KiB
C
|
/*
|
||
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||
|
*
|
||
|
* This source code is licensed under the MIT license found in the
|
||
|
* LICENSE file in the root directory of this source tree.
|
||
|
*/
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include <cstdint>
|
||
|
#include <unordered_map>
|
||
|
#include <utility>
|
||
|
#include <vector>
|
||
|
|
||
|
#include <jsi/jsi.h>
|
||
|
|
||
|
namespace facebook {
|
||
|
namespace hermes {
|
||
|
namespace inspector {
|
||
|
namespace chrome {
|
||
|
|
||
|
/// Well-known object group names
|
||
|
|
||
|
/**
|
||
|
* Objects created as a result of the Debugger.paused notification (e.g. scope
|
||
|
* objects) are placed in the "backtrace" object group. This object group is
|
||
|
* cleared when the VM resumes.
|
||
|
*/
|
||
|
extern const char *BacktraceObjectGroup;
|
||
|
|
||
|
/**
|
||
|
* Objects that are created as a result of a console evaluation are placed in
|
||
|
* the "console" object group. This object group is cleared when the client
|
||
|
* clears the console.
|
||
|
*/
|
||
|
extern const char *ConsoleObjectGroup;
|
||
|
|
||
|
/**
|
||
|
* RemoteObjectsTable manages the mapping of string object ids to scope metadata
|
||
|
* or actual JSI objects. The debugger vends these ids to the client so that the
|
||
|
* client can perform operations on the ids (e.g. enumerate properties on the
|
||
|
* object backed by the id). See Runtime.RemoteObjectId in the CDT docs for
|
||
|
* more details.
|
||
|
*
|
||
|
* Note that object handles are not ref-counted. Suppose an object foo is mapped
|
||
|
* to object id "objId" and is also in object group "objGroup". Then *either* of
|
||
|
* `releaseObject("objId")` or `releaseObjectGroup("objGroup")` will remove foo
|
||
|
* from the table. This matches the behavior of object groups in CDT.
|
||
|
*/
|
||
|
class RemoteObjectsTable {
|
||
|
public:
|
||
|
RemoteObjectsTable();
|
||
|
~RemoteObjectsTable();
|
||
|
|
||
|
RemoteObjectsTable(const RemoteObjectsTable &) = delete;
|
||
|
RemoteObjectsTable &operator=(const RemoteObjectsTable &) = delete;
|
||
|
|
||
|
/**
|
||
|
* addScope adds the provided (frameIndex, scopeIndex) mapping to the table.
|
||
|
* If objectGroup is non-empty, then the scope object is also added to that
|
||
|
* object group for releasing via releaseObjectGroup. Returns an object id.
|
||
|
*/
|
||
|
std::string addScope(
|
||
|
std::pair<uint32_t, uint32_t> frameAndScopeIndex,
|
||
|
const std::string &objectGroup);
|
||
|
|
||
|
/**
|
||
|
* addValue adds the JSI value to the table. If objectGroup is non-empty, then
|
||
|
* the scope object is also added to that object group for releasing via
|
||
|
* releaseObjectGroup. Returns an object id.
|
||
|
*/
|
||
|
std::string addValue(
|
||
|
::facebook::jsi::Value value,
|
||
|
const std::string &objectGroup);
|
||
|
|
||
|
/**
|
||
|
* Retrieves the (frameIndex, scopeIndex) associated with this object id, or
|
||
|
* nullptr if no mapping exists. The pointer stays valid as long as you only
|
||
|
* call const methods on this class.
|
||
|
*/
|
||
|
const std::pair<uint32_t, uint32_t> *getScope(const std::string &objId) const;
|
||
|
|
||
|
/**
|
||
|
* Retrieves the JSI value associated with this object id, or nullptr if no
|
||
|
* mapping exists. The pointer stays valid as long as you only call const
|
||
|
* methods on this class.
|
||
|
*/
|
||
|
const ::facebook::jsi::Value *getValue(const std::string &objId) const;
|
||
|
|
||
|
/**
|
||
|
* Retrieves the object group that this object id is in, or empty string if it
|
||
|
* isn't in an object group. The returned pointer is only guaranteed to be
|
||
|
* valid until the next call to this class.
|
||
|
*/
|
||
|
std::string getObjectGroup(const std::string &objId) const;
|
||
|
|
||
|
/**
|
||
|
* Removes the scope or JSI value backed by the provided object ID from the
|
||
|
* table.
|
||
|
*/
|
||
|
void releaseObject(const std::string &objId);
|
||
|
|
||
|
/**
|
||
|
* Removes all objects that are part of the provided object group from the
|
||
|
* table.
|
||
|
*/
|
||
|
void releaseObjectGroup(const std::string &objectGroup);
|
||
|
|
||
|
private:
|
||
|
void releaseObject(int64_t id);
|
||
|
|
||
|
int64_t scopeId_ = -1;
|
||
|
int64_t valueId_ = 1;
|
||
|
|
||
|
std::unordered_map<int64_t, std::pair<uint32_t, uint32_t>> scopes_;
|
||
|
std::unordered_map<int64_t, ::facebook::jsi::Value> values_;
|
||
|
std::unordered_map<int64_t, std::string> idToGroup_;
|
||
|
std::unordered_map<std::string, std::vector<int64_t>> groupToIds_;
|
||
|
};
|
||
|
|
||
|
} // namespace chrome
|
||
|
} // namespace inspector
|
||
|
} // namespace hermes
|
||
|
} // namespace facebook
|