Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
util: print External address from inspect
Fixes: #28250
  • Loading branch information
rosaxxny committed Jul 23, 2020
commit 9d071d96b26654b08b402a3db8e781cef95f1313
7 changes: 5 additions & 2 deletions lib/internal/util/inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const {
kRejected,
previewEntries,
getConstructorName: internalGetConstructorName,
getExternalValue,
propertyFilter: {
ALL_PROPERTIES,
ONLY_ENUMERABLE
Expand Down Expand Up @@ -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);
return ctx.stylize(`[External: ${address}]`, 'special');
}
return `${getCtxStyle(value, constructor, tag)}{}`;
}
braces[0] = `${getCtxStyle(value, constructor, tag)}{`;
Expand Down
17 changes: 17 additions & 0 deletions src/node_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ using v8::Array;
using v8::ArrayBufferView;
using v8::Boolean;
using v8::Context;
using v8::External;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Global;
Expand All @@ -19,6 +20,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;
Expand Down Expand Up @@ -68,6 +70,20 @@ static void GetConstructorName(
args.GetReturnValue().Set(name);
}

static void GetExternalValue(
const FunctionCallbackInfo<Value>& args) {
CHECK(args[0]->IsExternal());
auto isolate = args.GetIsolate();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is nice! Thank you!

This is not a blocker at all, but I'd prefer specify the type

Suggested change
auto isolate = args.GetIsolate();
Isolate* isolate = args.GetIsolate();

Just a sugestion, not a blocker.

Local<External> external = args[0].As<External>();

void* ptr = external->Value();
char val[20];
snprintf(val, sizeof(val), "%p", ptr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

%p can either format the pointer as 1234abcde or 0x1234abcd, and there's also potential inconsistency around NULL pointers. I'd cast the pointer to uint64_t and format it with PRIx64 from <cinttypes>.

An alternative solution is to turn the pointer into a BigInt with v8::BigInt::NewFromUnsigned() and do the formatting in JS land with value.toString(16).


MaybeLocal<String> ret = String::NewFromUtf8(isolate, val);
args.GetReturnValue().Set(ret.ToLocalChecked());
}

static void GetPromiseDetails(const FunctionCallbackInfo<Value>& args) {
// Return undefined if it's not a Promise.
if (!args[0]->IsPromise())
Expand Down Expand Up @@ -314,6 +330,7 @@ void Initialize(Local<Object> 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);
Expand Down
4 changes: 2 additions & 2 deletions test/parallel/test-util-inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: .*?\]$/);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check that the value is a non-empty hex string?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/^\[External: .*?\]$/);
/^\[External: [0-9a-f]+\]$/);


{
const regexp = /regexp/;
Expand Down