Skip to content

Commit c584c3e

Browse files
cjihrigrvagg
authored andcommitted
util,src: allow lookup of hidden values
This commit adds an internal util method that makes hidden values in the C++ layer visible in JS. PR-URL: #3988 Reviewed-By: Trevor Norris <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]>
1 parent a863e8d commit c584c3e

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

lib/internal/util.js

+3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
'use strict';
22

3+
const binding = process.binding('util');
34
const prefix = '(node) ';
45

6+
exports.getHiddenValue = binding.getHiddenValue;
7+
58
// All the internal deprecations have to use this function only, as this will
69
// prepend the prefix to the actual message.
710
exports.deprecate = function(fn, msg) {

src/node_util.cc

+19
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ using v8::Context;
1010
using v8::FunctionCallbackInfo;
1111
using v8::Local;
1212
using v8::Object;
13+
using v8::String;
1314
using v8::Value;
1415

1516
static void IsMapIterator(const FunctionCallbackInfo<Value>& args) {
@@ -28,13 +29,31 @@ static void IsPromise(const FunctionCallbackInfo<Value>& args) {
2829
args.GetReturnValue().Set(args[0]->IsPromise());
2930
}
3031

32+
33+
static void GetHiddenValue(const FunctionCallbackInfo<Value>& args) {
34+
Environment* env = Environment::GetCurrent(args);
35+
36+
if (!args[0]->IsObject())
37+
return env->ThrowTypeError("obj must be an object");
38+
39+
if (!args[1]->IsString())
40+
return env->ThrowTypeError("name must be a string");
41+
42+
Local<Object> obj = args[0].As<Object>();
43+
Local<String> name = args[1].As<String>();
44+
45+
args.GetReturnValue().Set(obj->GetHiddenValue(name));
46+
}
47+
48+
3149
void Initialize(Local<Object> target,
3250
Local<Value> unused,
3351
Local<Context> context) {
3452
Environment* env = Environment::GetCurrent(context);
3553
env->SetMethod(target, "isMapIterator", IsMapIterator);
3654
env->SetMethod(target, "isSetIterator", IsSetIterator);
3755
env->SetMethod(target, "isPromise", IsPromise);
56+
env->SetMethod(target, "getHiddenValue", GetHiddenValue);
3857
}
3958

4059
} // namespace util

test/parallel/test-util-internal.js

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
'use strict';
2+
// Flags: --expose_internals
3+
4+
const common = require('../common');
5+
const assert = require('assert');
6+
const internalUtil = require('internal/util');
7+
8+
function getHiddenValue(obj, name) {
9+
return function() {
10+
internalUtil.getHiddenValue(obj, name);
11+
};
12+
}
13+
14+
assert.throws(getHiddenValue(), /obj must be an object/);
15+
assert.throws(getHiddenValue(null, 'foo'), /obj must be an object/);
16+
assert.throws(getHiddenValue(undefined, 'foo'), /obj must be an object/);
17+
assert.throws(getHiddenValue('bar', 'foo'), /obj must be an object/);
18+
assert.throws(getHiddenValue(85, 'foo'), /obj must be an object/);
19+
assert.throws(getHiddenValue({}), /name must be a string/);
20+
assert.throws(getHiddenValue({}, null), /name must be a string/);
21+
assert.throws(getHiddenValue({}, []), /name must be a string/);
22+
assert.deepEqual(internalUtil.getHiddenValue({}, 'foo'), undefined);
23+
24+
let arrowMessage;
25+
26+
try {
27+
require('../fixtures/syntax/bad_syntax');
28+
} catch (err) {
29+
arrowMessage = internalUtil.getHiddenValue(err, 'arrowMessage');
30+
}
31+
32+
assert(/bad_syntax\.js:1/.test(arrowMessage));

0 commit comments

Comments
 (0)