#include "diagnosticfilename-inl.h"
#include "env-inl.h"
#include "memory_tracker-inl.h"
#include "node_external_reference.h"
#include "path.h"
#include "permission/permission.h"
#include "stream_base-inl.h"
#include "util-inl.h"
// Copied from https://github.com/nodejs/node/blob/b07dc4d19fdbc15b4f76557dc45b3ce3a43ad0c3/src/util.cc#L36-L41.
#ifdef _WIN32
#include // _S_IREAD _S_IWRITE
#ifndef S_IRUSR
#define S_IRUSR _S_IREAD
#endif // S_IRUSR
#ifndef S_IWUSR
#define S_IWUSR _S_IWRITE
#endif // S_IWUSR
#endif
using v8::Array;
using v8::Boolean;
using v8::Context;
using v8::Data;
using v8::EmbedderGraph;
using v8::EscapableHandleScope;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Global;
using v8::HandleScope;
using v8::HeapProfiler;
using v8::HeapSnapshot;
using v8::Isolate;
using v8::JustVoid;
using v8::Local;
using v8::Maybe;
using v8::MaybeLocal;
using v8::Nothing;
using v8::Number;
using v8::Object;
using v8::ObjectTemplate;
using v8::String;
using v8::Uint8Array;
using v8::Value;
namespace node {
namespace heap {
class JSGraphJSNode : public EmbedderGraph::Node {
public:
const char* Name() override { return ""; }
size_t SizeInBytes() override { return 0; }
bool IsEmbedderNode() override { return false; }
Local V8Value() { return PersistentToLocal::Strong(persistent_); }
JSGraphJSNode(Isolate* isolate, Local val) : persistent_(isolate, val) {
CHECK(!val.IsEmpty());
}
struct Equal {
inline bool operator()(JSGraphJSNode* a, JSGraphJSNode* b) const {
Local data_a = a->V8Value();
Local data_b = a->V8Value();
if (data_a->IsValue()) {
if (!data_b->IsValue()) {
return false;
}
return data_a.As()->SameValue(data_b.As());
}
return data_a == data_b;
}
};
private:
Global persistent_;
};
class JSGraph : public EmbedderGraph {
public:
explicit JSGraph(Isolate* isolate) : isolate_(isolate) {}
Node* V8Node(const Local<:data>& value) override {
std::unique_ptr n { new JSGraphJSNode(isolate_, value) };
auto it = engine_nodes_.find(n.get());
if (it != engine_nodes_.end())
return *it;
engine_nodes_.insert(n.get());
return AddNode(std::unique_ptr(n.release()));
}
Node* V8Node(const Local<:value>& value) override {
return V8Node(v8::Local<:data>(value));
}
Node* AddNode(std::unique_ptr node) override {
Node* n = node.get();
nodes_.emplace(std::move(node));
return n;
}
void AddEdge(Node* from, Node* to, const char* name = nullptr) override {
edges_[from].insert(std::make_pair(name, to));
}
MaybeLocal CreateObject() const {
EscapableHandleScope handle_scope(isolate_);
Local context = isolate_->GetCurrentContext();
Environment* env = Environment::GetCurrent(context);
std::unordered_map> info_objects;
Local nodes = Array::New(isolate_, nodes_.size());
Local edges_string = FIXED_ONE_BYTE_STRING(isolate_, "edges");
Local is_root_string = FIXED_ONE_BYTE_STRING(isolate_, "isRoot");
Local name_string = env->name_string();
Local size_string = env->size_string();
Local value_string = env->value_string();
Local wraps_string = FIXED_ONE_BYTE_STRING(isolate_, "wraps");
Local to_string = FIXED_ONE_BYTE_STRING(isolate_, "to");
for (const std::unique_ptr& n : nodes_)
info_objects[n.get()] = Object::New(isolate_);
{
HandleScope handle_scope(isolate_);
size_t i = 0;
for (const std::unique_ptr& n : nodes_) {
Local