#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::LocalVector; using v8::Object; using v8::Value; namespace node { namespace internal_only_v8 { class PrototypeChainHas : public v8::QueryObjectPredicate { public: PrototypeChainHas(Local context, Local 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) override { Local creation_context; if (!object->GetCreationContext().ToLocal(&creation_context)) { return false; } if (creation_context != context_) { return false; } for (Local proto = object->GetPrototypeV2(); proto->IsObject(); proto = proto.As()->GetPrototypeV2()) { if (search_ == proto) return true; } return false; } private: Local context_; Local search_; }; void QueryObjects(const FunctionCallbackInfo& args) { CHECK_EQ(args.Length(), 1); Isolate* isolate = args.GetIsolate(); if (!args[0]->IsObject()) { args.GetReturnValue().Set(Array::New(isolate)); return; } Local proto = args[0].As(); Local context = isolate->GetCurrentContext(); PrototypeChainHas prototype_chain_has(context, proto.As()); std::vector> out; isolate->GetHeapProfiler()->QueryObjects(context, &prototype_chain_has, &out); LocalVector result(isolate); 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 target, Local unused, Local 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)