Skip to content

Commit 470384e

Browse files
joyeecheungtargos
authored andcommitted
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. PR-URL: #45379 Backport-PR-URL: #45674 Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Signed-off-by: Daeyeon Jeong <daeyeon.dev@gmail.com>
1 parent b297dd5 commit 470384e

File tree

7 files changed

+51
-94
lines changed

7 files changed

+51
-94
lines changed

lib/internal/bootstrap/node.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,9 @@ const {
7676
exposeLazyInterfaces,
7777
} = require('internal/util');
7878
const {
79-
exiting_aliased_Uint32Array,
80-
getHiddenValue,
79+
privateSymbols: {
80+
exiting_aliased_Uint32Array,
81+
},
8182
} = internalBinding('util');
8283

8384
setupProcessObject();
@@ -87,8 +88,7 @@ setupBuffer();
8788

8889
process.domain = null;
8990
{
90-
const exitingAliasedUint32Array =
91-
getHiddenValue(process, exiting_aliased_Uint32Array);
91+
const exitingAliasedUint32Array = process[exiting_aliased_Uint32Array];
9292
ObjectDefineProperty(process, '_exiting', {
9393
__proto__: null,
9494
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
@@ -816,16 +816,14 @@ const fatalExceptionStackEnhancers = {
816816
}
817817
};
818818

819+
const {
820+
privateSymbols: {
821+
arrow_message_private_symbol,
822+
}
823+
} = internalBinding('util');
819824
// Ensures the printed error line is from user code.
820-
let _kArrowMessagePrivateSymbol, _setHiddenValue;
821825
function setArrowMessage(err, arrowMessage) {
822-
if (!_kArrowMessagePrivateSymbol) {
823-
({
824-
arrow_message_private_symbol: _kArrowMessagePrivateSymbol,
825-
setHiddenValue: _setHiddenValue,
826-
} = internalBinding('util'));
827-
}
828-
_setHiddenValue(err, _kArrowMessagePrivateSymbol, arrowMessage);
826+
err[arrow_message_private_symbol] = arrowMessage;
829827
}
830828

831829
// 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 & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ using v8::Object;
2626
using v8::ONLY_CONFIGURABLE;
2727
using v8::ONLY_ENUMERABLE;
2828
using v8::ONLY_WRITABLE;
29-
using v8::Private;
3029
using v8::Promise;
3130
using v8::PropertyFilter;
3231
using v8::Proxy;
@@ -159,44 +158,6 @@ static void PreviewEntries(const FunctionCallbackInfo<Value>& args) {
159158
Array::New(env->isolate(), ret, arraysize(ret)));
160159
}
161160

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-
200161
static void Sleep(const FunctionCallbackInfo<Value>& args) {
201162
CHECK(args[0]->IsUint32());
202163
uint32_t msec = args[0].As<Uint32>()->Value();
@@ -386,8 +347,6 @@ static void ToUSVString(const FunctionCallbackInfo<Value>& args) {
386347
}
387348

388349
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
389-
registry->Register(GetHiddenValue);
390-
registry->Register(SetHiddenValue);
391350
registry->Register(GetPromiseDetails);
392351
registry->Register(GetProxyDetails);
393352
registry->Register(PreviewEntries);
@@ -412,16 +371,22 @@ void Initialize(Local<Object> target,
412371
Environment* env = Environment::GetCurrent(context);
413372
Isolate* isolate = env->isolate();
414373

415-
#define V(name, _) \
416-
target->Set(context, \
417-
FIXED_ONE_BYTE_STRING(env->isolate(), #name), \
418-
Integer::NewFromUnsigned(env->isolate(), index++)).Check();
419374
{
420-
uint32_t index = 0;
375+
Local<v8::ObjectTemplate> tmpl = v8::ObjectTemplate::New(isolate);
376+
#define V(PropertyName, _) \
377+
tmpl->Set(FIXED_ONE_BYTE_STRING(env->isolate(), #PropertyName), \
378+
env->PropertyName());
379+
421380
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
422-
}
423381
#undef V
424382

383+
target
384+
->Set(context,
385+
FIXED_ONE_BYTE_STRING(isolate, "privateSymbols"),
386+
tmpl->NewInstance(context).ToLocalChecked())
387+
.Check();
388+
}
389+
425390
#define V(name) \
426391
target->Set(context, \
427392
FIXED_ONE_BYTE_STRING(env->isolate(), #name), \
@@ -432,8 +397,6 @@ void Initialize(Local<Object> target,
432397
V(kRejected);
433398
#undef V
434399

435-
SetMethodNoSideEffect(context, target, "getHiddenValue", GetHiddenValue);
436-
SetMethod(context, target, "setHiddenValue", SetHiddenValue);
437400
SetMethodNoSideEffect(
438401
context, target, "getPromiseDetails", GetPromiseDetails);
439402
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy