Skip to content

Commit 9d071d9

Browse files
committed
util: print External address from inspect
Fixes: #28250
1 parent 090ad7d commit 9d071d9

File tree

3 files changed

+24
-4
lines changed

3 files changed

+24
-4
lines changed

lib/internal/util/inspect.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ const {
6363
kRejected,
6464
previewEntries,
6565
getConstructorName: internalGetConstructorName,
66+
getExternalValue,
6667
propertyFilter: {
6768
ALL_PROPERTIES,
6869
ONLY_ENUMERABLE
@@ -977,8 +978,10 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
977978
}
978979
} else {
979980
if (keys.length === 0 && protoProps === undefined) {
980-
if (isExternal(value))
981-
return ctx.stylize('[External]', 'special');
981+
if (isExternal(value)) {
982+
const address = getExternalValue(value);
983+
return ctx.stylize(`[External: ${address}]`, 'special');
984+
}
982985
return `${getCtxStyle(value, constructor, tag)}{}`;
983986
}
984987
braces[0] = `${getCtxStyle(value, constructor, tag)}{`;

src/node_util.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ using v8::Array;
1111
using v8::ArrayBufferView;
1212
using v8::Boolean;
1313
using v8::Context;
14+
using v8::External;
1415
using v8::FunctionCallbackInfo;
1516
using v8::FunctionTemplate;
1617
using v8::Global;
@@ -19,6 +20,7 @@ using v8::Integer;
1920
using v8::Isolate;
2021
using v8::KeyCollectionMode;
2122
using v8::Local;
23+
using v8::MaybeLocal;
2224
using v8::Object;
2325
using v8::ONLY_CONFIGURABLE;
2426
using v8::ONLY_ENUMERABLE;
@@ -68,6 +70,20 @@ static void GetConstructorName(
6870
args.GetReturnValue().Set(name);
6971
}
7072

73+
static void GetExternalValue(
74+
const FunctionCallbackInfo<Value>& args) {
75+
CHECK(args[0]->IsExternal());
76+
auto isolate = args.GetIsolate();
77+
Local<External> external = args[0].As<External>();
78+
79+
void* ptr = external->Value();
80+
char val[20];
81+
snprintf(val, sizeof(val), "%p", ptr);
82+
83+
MaybeLocal<String> ret = String::NewFromUtf8(isolate, val);
84+
args.GetReturnValue().Set(ret.ToLocalChecked());
85+
}
86+
7187
static void GetPromiseDetails(const FunctionCallbackInfo<Value>& args) {
7288
// Return undefined if it's not a Promise.
7389
if (!args[0]->IsPromise())
@@ -314,6 +330,7 @@ void Initialize(Local<Object> target,
314330
env->SetMethodNoSideEffect(target, "getOwnNonIndexProperties",
315331
GetOwnNonIndexProperties);
316332
env->SetMethodNoSideEffect(target, "getConstructorName", GetConstructorName);
333+
env->SetMethodNoSideEffect(target, "getExternalValue", GetExternalValue);
317334
env->SetMethod(target, "sleep", Sleep);
318335

319336
env->SetMethod(target, "arrayBufferViewHasBuffer", ArrayBufferViewHasBuffer);

test/parallel/test-util-inspect.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ assert.strictEqual(
147147
"[String: 'hello'] { [length]: 5, [Symbol(foo)]: 123 }"
148148
);
149149

150-
assert.strictEqual(util.inspect((new JSStream())._externalStream),
151-
'[External]');
150+
assert.match(util.inspect((new JSStream())._externalStream),
151+
/^\[External: .*?\]$/);
152152

153153
{
154154
const regexp = /regexp/;

0 commit comments

Comments
 (0)