forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 0
/
internal_only_v8.cc
85 lines (74 loc) Β· 2.51 KB
/
internal_only_v8.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include "node_binding.h"
#include "node_external_reference.h"
#include "util-inl.h"
#include "v8-profiler.h"
#include "v8.h"
using v8::Array;
using v8::Context;
using v8::FunctionCallbackInfo;
using v8::Global;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::Value;
namespace node {
namespace internal_only_v8 {
class PrototypeChainHas : public v8::QueryObjectPredicate {
public:
PrototypeChainHas(Local<Context> context, Local<Object> search)
: context_(context), search_(search) {}
// What we can do in the filter can be quite limited, but looking up
// the prototype chain is something that the inspector console API
// queryObject() does so it is supported.
bool Filter(Local<Object> object) override {
Local<Context> creation_context;
if (!object->GetCreationContext().ToLocal(&creation_context)) {
return false;
}
if (creation_context != context_) {
return false;
}
for (Local<Value> proto = object->GetPrototype(); proto->IsObject();
proto = proto.As<Object>()->GetPrototype()) {
if (search_ == proto) return true;
}
return false;
}
private:
Local<Context> context_;
Local<Object> search_;
};
void QueryObjects(const FunctionCallbackInfo<Value>& args) {
CHECK_EQ(args.Length(), 1);
Isolate* isolate = args.GetIsolate();
if (!args[0]->IsObject()) {
args.GetReturnValue().Set(Array::New(isolate));
return;
}
Local<Object> proto = args[0].As<Object>();
Local<Context> context = isolate->GetCurrentContext();
PrototypeChainHas prototype_chain_has(context, proto.As<Object>());
std::vector<Global<Object>> out;
isolate->GetHeapProfiler()->QueryObjects(context, &prototype_chain_has, &out);
std::vector<Local<Value>> result;
result.reserve(out.size());
for (size_t i = 0; i < out.size(); ++i) {
result.push_back(out[i].Get(isolate));
}
args.GetReturnValue().Set(Array::New(isolate, result.data(), result.size()));
}
void Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
SetMethod(context, target, "queryObjects", QueryObjects);
}
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(QueryObjects);
}
} // namespace internal_only_v8
} // namespace node
NODE_BINDING_CONTEXT_AWARE_INTERNAL(internal_only_v8,
node::internal_only_v8::Initialize)
NODE_BINDING_EXTERNAL_REFERENCE(
internal_only_v8, node::internal_only_v8::RegisterExternalReferences)