Skip to content

Commit 2ac9634

Browse files
committed
util: use private symbols in JS land directly
Instead of calling into C++ to use the private symbols, use an ObjectTemplate to create an object that holds the symbols and use them directly from JS land.
1 parent e9a9e1e commit 2ac9634

File tree

7 files changed

+51
-93
lines changed

7 files changed

+51
-93
lines changed

lib/internal/bootstrap/node.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,9 @@ const {
8080
validateInteger,
8181
} = require('internal/validators');
8282
const {
83-
exit_info_private_symbol,
84-
getHiddenValue,
83+
privateSymbols: {
84+
exit_info_private_symbol,
85+
},
8586
kExitCode,
8687
kExiting,
8788
kHasExitCode,
@@ -96,8 +97,7 @@ process.domain = null;
9697

9798
// process._exiting and process.exitCode
9899
{
99-
const fields = getHiddenValue(process, exit_info_private_symbol);
100-
100+
const fields = process[exit_info_private_symbol];
101101
ObjectDefineProperty(process, '_exiting', {
102102
__proto__: null,
103103
get() {

lib/internal/buffer.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@ const {
3232
utf8Write,
3333
getZeroFillToggle
3434
} = internalBinding('buffer');
35+
3536
const {
36-
untransferable_object_private_symbol,
37-
setHiddenValue,
37+
privateSymbols: {
38+
untransferable_object_private_symbol,
39+
},
3840
} = internalBinding('util');
3941

4042
// Temporary buffers to convert numbers.
@@ -1048,7 +1050,7 @@ function addBufferPrototypeMethods(proto) {
10481050
function markAsUntransferable(obj) {
10491051
if ((typeof obj !== 'object' && typeof obj !== 'function') || obj === null)
10501052
return; // This object is a primitive and therefore already untransferable.
1051-
setHiddenValue(obj, untransferable_object_private_symbol, true);
1053+
obj[untransferable_object_private_symbol] = true;
10521054
}
10531055

10541056
// A toggle used to access the zero fill setting of the array buffer allocator

lib/internal/errors.js

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -809,16 +809,14 @@ const fatalExceptionStackEnhancers = {
809809
}
810810
};
811811

812+
const {
813+
privateSymbols: {
814+
arrow_message_private_symbol,
815+
}
816+
} = internalBinding('util');
812817
// Ensures the printed error line is from user code.
813-
let _kArrowMessagePrivateSymbol, _setHiddenValue;
814818
function setArrowMessage(err, arrowMessage) {
815-
if (!_kArrowMessagePrivateSymbol) {
816-
({
817-
arrow_message_private_symbol: _kArrowMessagePrivateSymbol,
818-
setHiddenValue: _setHiddenValue,
819-
} = internalBinding('util'));
820-
}
821-
_setHiddenValue(err, _kArrowMessagePrivateSymbol, arrowMessage);
819+
err[arrow_message_private_symbol] = arrowMessage;
822820
}
823821

824822
// Hide stack lines before the first user code line.

lib/internal/util.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ const {
4242
} = require('internal/errors');
4343
const { signals } = internalBinding('constants').os;
4444
const {
45-
getHiddenValue,
46-
setHiddenValue,
47-
arrow_message_private_symbol: kArrowMessagePrivateSymbolIndex,
48-
decorated_private_symbol: kDecoratedPrivateSymbolIndex,
45+
privateSymbols: {
46+
arrow_message_private_symbol,
47+
decorated_private_symbol,
48+
},
4949
sleep: _sleep,
5050
toUSVString: _toUSVString,
5151
} = internalBinding('util');
@@ -143,15 +143,14 @@ function deprecate(fn, msg, code, useEmitSync) {
143143
}
144144

145145
function decorateErrorStack(err) {
146-
if (!(isError(err) && err.stack) ||
147-
getHiddenValue(err, kDecoratedPrivateSymbolIndex) === true)
146+
if (!(isError(err) && err.stack) || err[decorated_private_symbol])
148147
return;
149148

150-
const arrow = getHiddenValue(err, kArrowMessagePrivateSymbolIndex);
149+
const arrow = err[arrow_message_private_symbol];
151150

152151
if (arrow) {
153152
err.stack = arrow + err.stack;
154-
setHiddenValue(err, kDecoratedPrivateSymbolIndex, true);
153+
err[decorated_private_symbol] = true;
155154
}
156155
}
157156

src/node_util.cc

Lines changed: 12 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -159,44 +159,6 @@ static void PreviewEntries(const FunctionCallbackInfo<Value>& args) {
159159
Array::New(env->isolate(), ret, arraysize(ret)));
160160
}
161161

162-
inline Local<Private> IndexToPrivateSymbol(Environment* env, uint32_t index) {
163-
#define V(name, _) &Environment::name,
164-
static Local<Private> (Environment::*const methods[])() const = {
165-
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
166-
};
167-
#undef V
168-
CHECK_LT(index, arraysize(methods));
169-
return (env->*methods[index])();
170-
}
171-
172-
static void GetHiddenValue(const FunctionCallbackInfo<Value>& args) {
173-
Environment* env = Environment::GetCurrent(args);
174-
175-
CHECK(args[0]->IsObject());
176-
CHECK(args[1]->IsUint32());
177-
178-
Local<Object> obj = args[0].As<Object>();
179-
uint32_t index = args[1].As<Uint32>()->Value();
180-
Local<Private> private_symbol = IndexToPrivateSymbol(env, index);
181-
Local<Value> ret;
182-
if (obj->GetPrivate(env->context(), private_symbol).ToLocal(&ret))
183-
args.GetReturnValue().Set(ret);
184-
}
185-
186-
static void SetHiddenValue(const FunctionCallbackInfo<Value>& args) {
187-
Environment* env = Environment::GetCurrent(args);
188-
189-
CHECK(args[0]->IsObject());
190-
CHECK(args[1]->IsUint32());
191-
192-
Local<Object> obj = args[0].As<Object>();
193-
uint32_t index = args[1].As<Uint32>()->Value();
194-
Local<Private> private_symbol = IndexToPrivateSymbol(env, index);
195-
bool ret;
196-
if (obj->SetPrivate(env->context(), private_symbol, args[2]).To(&ret))
197-
args.GetReturnValue().Set(ret);
198-
}
199-
200162
static void Sleep(const FunctionCallbackInfo<Value>& args) {
201163
CHECK(args[0]->IsUint32());
202164
uint32_t msec = args[0].As<Uint32>()->Value();
@@ -379,8 +341,6 @@ static void ToUSVString(const FunctionCallbackInfo<Value>& args) {
379341
}
380342

381343
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
382-
registry->Register(GetHiddenValue);
383-
registry->Register(SetHiddenValue);
384344
registry->Register(GetPromiseDetails);
385345
registry->Register(GetProxyDetails);
386346
registry->Register(PreviewEntries);
@@ -404,16 +364,22 @@ void Initialize(Local<Object> target,
404364
Environment* env = Environment::GetCurrent(context);
405365
Isolate* isolate = env->isolate();
406366

407-
#define V(name, _) \
408-
target->Set(context, \
409-
FIXED_ONE_BYTE_STRING(env->isolate(), #name), \
410-
Integer::NewFromUnsigned(env->isolate(), index++)).Check();
411367
{
412-
uint32_t index = 0;
368+
Local<v8::ObjectTemplate> tmpl = v8::ObjectTemplate::New(isolate);
369+
#define V(PropertyName, _) \
370+
tmpl->Set(FIXED_ONE_BYTE_STRING(env->isolate(), #PropertyName), \
371+
env->PropertyName());
372+
413373
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
414-
}
415374
#undef V
416375

376+
target
377+
->Set(context,
378+
FIXED_ONE_BYTE_STRING(isolate, "privateSymbols"),
379+
tmpl->NewInstance(context).ToLocalChecked())
380+
.Check();
381+
}
382+
417383
#define V(name) \
418384
target->Set(context, \
419385
FIXED_ONE_BYTE_STRING(env->isolate(), #name), \
@@ -435,8 +401,6 @@ void Initialize(Local<Object> target,
435401
V(kHasExitCode);
436402
#undef V
437403

438-
SetMethodNoSideEffect(context, target, "getHiddenValue", GetHiddenValue);
439-
SetMethod(context, target, "setHiddenValue", SetHiddenValue);
440404
SetMethodNoSideEffect(
441405
context, target, "getPromiseDetails", GetPromiseDetails);
442406
SetMethodNoSideEffect(context, target, "getProxyDetails", GetProxyDetails);

test/parallel/test-internal-util-decorate-error-stack.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ const fixtures = require('../common/fixtures');
55
const assert = require('assert');
66
const internalUtil = require('internal/util');
77
const { internalBinding } = require('internal/test/binding');
8-
const binding = internalBinding('util');
8+
const {
9+
privateSymbols: {
10+
arrow_message_private_symbol,
11+
decorated_private_symbol,
12+
}
13+
} = internalBinding('util');
914
const spawnSync = require('child_process').spawnSync;
1015

11-
const kArrowMessagePrivateSymbolIndex = binding.arrow_message_private_symbol;
12-
const kDecoratedPrivateSymbolIndex = binding.decorated_private_symbol;
13-
1416
const decorateErrorStack = internalUtil.decorateErrorStack;
1517

1618
// Verify that decorateErrorStack does not throw with non-objects.
@@ -73,9 +75,8 @@ const arrowMessage = 'arrow_message';
7375
err = new Error('foo');
7476
originalStack = err.stack;
7577

76-
binding.setHiddenValue(err, kArrowMessagePrivateSymbolIndex, arrowMessage);
78+
err[arrow_message_private_symbol] = arrowMessage;
7779
decorateErrorStack(err);
7880

7981
assert.strictEqual(err.stack, `${arrowMessage}${originalStack}`);
80-
assert.strictEqual(
81-
binding.getHiddenValue(err, kDecoratedPrivateSymbolIndex), true);
82+
assert.strictEqual(err[decorated_private_symbol], true);

test/parallel/test-util-internal.js

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,24 @@ const fixtures = require('../common/fixtures');
77
const { internalBinding } = require('internal/test/binding');
88

99
const {
10-
getHiddenValue,
11-
setHiddenValue,
12-
arrow_message_private_symbol: kArrowMessagePrivateSymbolIndex
10+
privateSymbols: {
11+
arrow_message_private_symbol,
12+
},
1313
} = internalBinding('util');
1414

15-
assert.strictEqual(
16-
getHiddenValue({}, kArrowMessagePrivateSymbolIndex),
17-
undefined);
18-
1915
const obj = {};
20-
assert.strictEqual(
21-
setHiddenValue(obj, kArrowMessagePrivateSymbolIndex, 'bar'),
22-
true);
23-
assert.strictEqual(
24-
getHiddenValue(obj, kArrowMessagePrivateSymbolIndex),
25-
'bar');
16+
assert.strictEqual(obj[arrow_message_private_symbol], undefined);
17+
18+
obj[arrow_message_private_symbol] = 'bar';
19+
assert.strictEqual(obj[arrow_message_private_symbol], 'bar');
20+
assert.deepStrictEqual(Reflect.ownKeys(obj), []);
2621

2722
let arrowMessage;
2823

2924
try {
3025
require(fixtures.path('syntax', 'bad_syntax'));
3126
} catch (err) {
32-
arrowMessage =
33-
getHiddenValue(err, kArrowMessagePrivateSymbolIndex);
27+
arrowMessage = err[arrow_message_private_symbol];
3428
}
3529

3630
assert.match(arrowMessage, /bad_syntax\.js:1/);

0 commit comments

Comments
 (0)