From d5e0adaf15e4e471d62b928b3d1b63d8f84d6b91 Mon Sep 17 00:00:00 2001 From: Matheus Marchini Date: Mon, 20 Aug 2018 14:52:27 -0300 Subject: [PATCH] src: inspect context objects (Node.js v10.x+) This patch teaches llnode how to inspect Context objects. This is useful to inspect context variables. PR-URL: https://github.com/nodejs/llnode/pull/201 Fixes: https://github.com/nodejs/llnode/issues/211 Reviewed-By: Joyee Cheung --- src/llv8-constants.cc | 4 ++++ src/llv8-constants.h | 4 ++++ src/llv8.cc | 46 +++++++++++++++++++++++++++++-------------- src/llv8.h | 10 ++++++++-- 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/llv8-constants.cc b/src/llv8-constants.cc index b9400156..16d2eebb 100644 --- a/src/llv8-constants.cc +++ b/src/llv8-constants.cc @@ -487,6 +487,9 @@ void Types::Load() { kFirstJSObjectType = LoadConstant("type_JSGlobalObject__JS_GLOBAL_OBJECT_TYPE"); + kFirstContextType = LoadConstant("FirstContextType"); + kLastContextType = LoadConstant("LastContextType"); + kHeapNumberType = LoadConstant("type_HeapNumber__HEAP_NUMBER_TYPE"); kMapType = LoadConstant("type_Map__MAP_TYPE"); kGlobalObjectType = @@ -508,6 +511,7 @@ void Types::Load() { kSharedFunctionInfoType = LoadConstant("type_SharedFunctionInfo__SHARED_FUNCTION_INFO_TYPE"); kScriptType = LoadConstant("type_Script__SCRIPT_TYPE"); + kScopeInfoType = LoadConstant("type_ScopeInfo__SCOPE_INFO_TYPE"); if (kJSAPIObjectType == -1) { common_->Load(); diff --git a/src/llv8-constants.h b/src/llv8-constants.h index 26b9e6a2..80fc6e14 100644 --- a/src/llv8-constants.h +++ b/src/llv8-constants.h @@ -475,6 +475,9 @@ class Types : public Module { int64_t kFirstNonstringType; int64_t kFirstJSObjectType; + int64_t kFirstContextType; + int64_t kLastContextType; + int64_t kHeapNumberType; int64_t kMapType; int64_t kGlobalObjectType; @@ -493,6 +496,7 @@ class Types : public Module { int64_t kJSDateType; int64_t kSharedFunctionInfoType; int64_t kScriptType; + int64_t kScopeInfoType; protected: void Load(); diff --git a/src/llv8.cc b/src/llv8.cc index 3ca4b537..d83bb7ad 100644 --- a/src/llv8.cc +++ b/src/llv8.cc @@ -389,10 +389,15 @@ std::string JSFunction::Inspect(InspectOptions* options, Error& err) { snprintf(tmp, sizeof(tmp), "\n context=0x%016" PRIx64, context.raw()); res += tmp; - std::string context_str = context.Inspect(err); - if (err.Fail()) return std::string(); + { + InspectOptions ctx_options; + ctx_options.detailed = true; + ctx_options.indent_depth = options->indent_depth + 1; + std::string context_str = context.Inspect(&ctx_options, err); + if (err.Fail()) return std::string(); - if (!context_str.empty()) res += ":" + context_str; + if (!context_str.empty()) res += ":" + context_str; + } if (options->print_source) { SharedFunctionInfo info = Info(err); @@ -821,6 +826,12 @@ std::string HeapObject::Inspect(InspectOptions* options, Error& err) { return pre + str.Inspect(options, err); } + if (type >= v8()->types()->kFirstContextType && + type <= v8()->types()->kLastContextType) { + Context ctx(this); + return pre + ctx.Inspect(options, err); + } + if (type == v8()->types()->kFixedArrayType) { FixedArray arr(this); return pre + arr.Inspect(options, err); @@ -1060,13 +1071,19 @@ HeapObject Context::GetScopeInfo(Error& err) { return info.GetScopeInfo(err); } -std::string Context::Inspect(Error& err) { +std::string Context::Inspect(InspectOptions* options, Error& err) { // Not enough postmortem information, return bare minimum if (v8()->shared_info()->kScopeInfoOffset == -1 && v8()->shared_info()->kNameOrScopeInfoOffset == -1) return std::string(); - std::string res = "detailed) { + return res + ">"; + } + + res += ": {\n"; Value previous = Previous(err); if (err.Fail()) return std::string(); @@ -1083,12 +1100,10 @@ std::string Context::Inspect(Error& err) { Smi local_count_smi = scope.ContextLocalCount(err); if (err.Fail()) return std::string(); - InspectOptions options; - HeapObject heap_previous = HeapObject(previous); if (heap_previous.Check()) { char tmp[128]; - snprintf(tmp, sizeof(tmp), " (previous)=0x%016" PRIx64, previous.raw()); + snprintf(tmp, sizeof(tmp), (options->get_indent_spaces() + "(previous)=0x%016" PRIx64).c_str(), previous.raw()); res += std::string(tmp) + ":,"; } @@ -1098,16 +1113,16 @@ std::string Context::Inspect(Error& err) { JSFunction closure = Closure(err); if (err.Fail()) return std::string(); char tmp[128]; - snprintf(tmp, sizeof(tmp), " (closure)=0x%016" PRIx64 " {", + snprintf(tmp, sizeof(tmp), (options->get_indent_spaces() + "(closure)=0x%016" PRIx64 " {").c_str(), closure.raw()); res += tmp; - InspectOptions options; - res += closure.Inspect(&options, err) + "}"; + InspectOptions closure_options; + res += closure.Inspect(&closure_options, err) + "}"; if (err.Fail()) return std::string(); } else { char tmp[128]; - snprintf(tmp, sizeof(tmp), " (scope_info)=0x%016" PRIx64, + snprintf(tmp, sizeof(tmp), (options->get_indent_spaces() + "(scope_info)=0x%016" PRIx64).c_str(), scope.raw()); res += std::string(tmp) + ":"; + return res + "}>"; } diff --git a/src/llv8.h b/src/llv8.h index 96818c6e..02ced191 100644 --- a/src/llv8.h +++ b/src/llv8.h @@ -44,14 +44,20 @@ class Value { : detailed(false), print_map(false), print_source(false), - length(kLength) {} + length(kLength), + indent_depth(1) {} static const unsigned int kLength = 16; + static const unsigned int kIndentSize = 2; + inline std::string get_indent_spaces() { + return std::string(indent_depth * kIndentSize, ' '); + } bool detailed; bool print_map; bool print_source; unsigned int length; + unsigned int indent_depth; }; Value(const Value& v) = default; @@ -390,7 +396,7 @@ class Context : public FixedArray { inline T GetEmbedderData(int64_t index, Error& err); inline Value ContextSlot(int index, Error& err); - std::string Inspect(Error& err); + std::string Inspect(InspectOptions *options, Error& err); private: inline JSFunction Closure(Error& err);