diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 13ec60f7773381..102d6f0f153d6a 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -63,6 +63,7 @@ const { kRejected, previewEntries, getConstructorName: internalGetConstructorName, + getExternalValue, propertyFilter: { ALL_PROPERTIES, ONLY_ENUMERABLE @@ -977,8 +978,10 @@ function formatRaw(ctx, value, recurseTimes, typedArray) { } } else { if (keys.length === 0 && protoProps === undefined) { - if (isExternal(value)) - return ctx.stylize('[External]', 'special'); + if (isExternal(value)) { + const address = getExternalValue(value).toString(16); + return ctx.stylize(`[External: ${address}]`, 'special'); + } return `${getCtxStyle(value, constructor, tag)}{}`; } braces[0] = `${getCtxStyle(value, constructor, tag)}{`; diff --git a/src/node_util.cc b/src/node_util.cc index 44148ba2b0958a..3b571180ca9d02 100644 --- a/src/node_util.cc +++ b/src/node_util.cc @@ -9,8 +9,10 @@ namespace util { using v8::ALL_PROPERTIES; using v8::Array; using v8::ArrayBufferView; +using v8::BigInt; using v8::Boolean; using v8::Context; +using v8::External; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Global; @@ -19,6 +21,7 @@ using v8::Integer; using v8::Isolate; using v8::KeyCollectionMode; using v8::Local; +using v8::MaybeLocal; using v8::Object; using v8::ONLY_CONFIGURABLE; using v8::ONLY_ENUMERABLE; @@ -68,6 +71,18 @@ static void GetConstructorName( args.GetReturnValue().Set(name); } +static void GetExternalValue( + const FunctionCallbackInfo& args) { + CHECK(args[0]->IsExternal()); + Isolate* isolate = args.GetIsolate(); + Local external = args[0].As(); + + void* ptr = external->Value(); + uint64_t value = reinterpret_cast(ptr); + Local ret = BigInt::NewFromUnsigned(isolate, value); + args.GetReturnValue().Set(ret); +} + static void GetPromiseDetails(const FunctionCallbackInfo& args) { // Return undefined if it's not a Promise. if (!args[0]->IsPromise()) @@ -271,6 +286,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(PreviewEntries); registry->Register(GetOwnNonIndexProperties); registry->Register(GetConstructorName); + registry->Register(GetExternalValue); registry->Register(Sleep); registry->Register(ArrayBufferViewHasBuffer); registry->Register(WeakReference::New); @@ -314,6 +330,7 @@ void Initialize(Local target, env->SetMethodNoSideEffect(target, "getOwnNonIndexProperties", GetOwnNonIndexProperties); env->SetMethodNoSideEffect(target, "getConstructorName", GetConstructorName); + env->SetMethodNoSideEffect(target, "getExternalValue", GetExternalValue); env->SetMethod(target, "sleep", Sleep); env->SetMethod(target, "arrayBufferViewHasBuffer", ArrayBufferViewHasBuffer); diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index 78184d85f6e9f3..3b0fc186160f24 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -147,8 +147,8 @@ assert.strictEqual( "[String: 'hello'] { [length]: 5, [Symbol(foo)]: 123 }" ); -assert.strictEqual(util.inspect((new JSStream())._externalStream), - '[External]'); +assert.match(util.inspect((new JSStream())._externalStream), + /^\[External: [0-9a-f]+\]$/); { const regexp = /regexp/;