summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoyee Cheung <joyeec9h3@gmail.com>2022-11-04 18:33:03 +0100
committerDanielle Adams <adamzdanielle@gmail.com>2023-01-04 20:31:57 -0500
commit2bd79a317f3edcecc7b0236fb207bad495329750 (patch)
treecd1680cafe02447f3f7a0c261327c08cbd5b1ff4
parentf762ed2ce5ce90b191ca2ae1da0f5780f1dcc04e (diff)
downloadnode-new-2bd79a317f3edcecc7b0236fb207bad495329750.tar.gz
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: https://github.com/nodejs/node/pull/45379 Backport-PR-URL: https://github.com/nodejs/node/pull/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>
-rw-r--r--lib/internal/bootstrap/node.js8
-rw-r--r--lib/internal/buffer.js8
-rw-r--r--lib/internal/errors.js14
-rw-r--r--lib/internal/util.js15
-rw-r--r--src/node_util.cc61
-rw-r--r--test/parallel/test-internal-util-decorate-error-stack.js15
-rw-r--r--test/parallel/test-util-internal.js24
7 files changed, 51 insertions, 94 deletions
diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js
index f31bc15f2a..cbca692e0e 100644
--- a/lib/internal/bootstrap/node.js
+++ b/lib/internal/bootstrap/node.js
@@ -77,8 +77,9 @@ const {
exposeInterface,
} = require('internal/util');
const {
- exiting_aliased_Uint32Array,
- getHiddenValue,
+ privateSymbols: {
+ exiting_aliased_Uint32Array,
+ },
} = internalBinding('util');
setupProcessObject();
@@ -88,8 +89,7 @@ setupBuffer();
process.domain = null;
{
- const exitingAliasedUint32Array =
- getHiddenValue(process, exiting_aliased_Uint32Array);
+ const exitingAliasedUint32Array = process[exiting_aliased_Uint32Array];
ObjectDefineProperty(process, '_exiting', {
__proto__: null,
get() {
diff --git a/lib/internal/buffer.js b/lib/internal/buffer.js
index bd38cf48a7..7b8331f475 100644
--- a/lib/internal/buffer.js
+++ b/lib/internal/buffer.js
@@ -32,9 +32,11 @@ const {
utf8Write,
getZeroFillToggle
} = internalBinding('buffer');
+
const {
- untransferable_object_private_symbol,
- setHiddenValue,
+ privateSymbols: {
+ untransferable_object_private_symbol,
+ },
} = internalBinding('util');
// Temporary buffers to convert numbers.
@@ -1048,7 +1050,7 @@ function addBufferPrototypeMethods(proto) {
function markAsUntransferable(obj) {
if ((typeof obj !== 'object' && typeof obj !== 'function') || obj === null)
return; // This object is a primitive and therefore already untransferable.
- setHiddenValue(obj, untransferable_object_private_symbol, true);
+ obj[untransferable_object_private_symbol] = true;
}
// A toggle used to access the zero fill setting of the array buffer allocator
diff --git a/lib/internal/errors.js b/lib/internal/errors.js
index 38c9d391d3..754479e63c 100644
--- a/lib/internal/errors.js
+++ b/lib/internal/errors.js
@@ -816,16 +816,14 @@ const fatalExceptionStackEnhancers = {
}
};
+const {
+ privateSymbols: {
+ arrow_message_private_symbol,
+ }
+} = internalBinding('util');
// Ensures the printed error line is from user code.
-let _kArrowMessagePrivateSymbol, _setHiddenValue;
function setArrowMessage(err, arrowMessage) {
- if (!_kArrowMessagePrivateSymbol) {
- ({
- arrow_message_private_symbol: _kArrowMessagePrivateSymbol,
- setHiddenValue: _setHiddenValue,
- } = internalBinding('util'));
- }
- _setHiddenValue(err, _kArrowMessagePrivateSymbol, arrowMessage);
+ err[arrow_message_private_symbol] = arrowMessage;
}
// Hide stack lines before the first user code line.
diff --git a/lib/internal/util.js b/lib/internal/util.js
index 615d4c36c1..5eb6598d6a 100644
--- a/lib/internal/util.js
+++ b/lib/internal/util.js
@@ -42,10 +42,10 @@ const {
} = require('internal/errors');
const { signals } = internalBinding('constants').os;
const {
- getHiddenValue,
- setHiddenValue,
- arrow_message_private_symbol: kArrowMessagePrivateSymbolIndex,
- decorated_private_symbol: kDecoratedPrivateSymbolIndex,
+ privateSymbols: {
+ arrow_message_private_symbol,
+ decorated_private_symbol,
+ },
sleep: _sleep,
toUSVString: _toUSVString,
} = internalBinding('util');
@@ -140,15 +140,14 @@ function deprecate(fn, msg, code) {
}
function decorateErrorStack(err) {
- if (!(isError(err) && err.stack) ||
- getHiddenValue(err, kDecoratedPrivateSymbolIndex) === true)
+ if (!(isError(err) && err.stack) || err[decorated_private_symbol])
return;
- const arrow = getHiddenValue(err, kArrowMessagePrivateSymbolIndex);
+ const arrow = err[arrow_message_private_symbol];
if (arrow) {
err.stack = arrow + err.stack;
- setHiddenValue(err, kDecoratedPrivateSymbolIndex, true);
+ err[decorated_private_symbol] = true;
}
}
diff --git a/src/node_util.cc b/src/node_util.cc
index f57bbc5605..4d6c757c2f 100644
--- a/src/node_util.cc
+++ b/src/node_util.cc
@@ -26,7 +26,6 @@ using v8::Object;
using v8::ONLY_CONFIGURABLE;
using v8::ONLY_ENUMERABLE;
using v8::ONLY_WRITABLE;
-using v8::Private;
using v8::Promise;
using v8::PropertyFilter;
using v8::Proxy;
@@ -159,44 +158,6 @@ static void PreviewEntries(const FunctionCallbackInfo<Value>& args) {
Array::New(env->isolate(), ret, arraysize(ret)));
}
-inline Local<Private> IndexToPrivateSymbol(Environment* env, uint32_t index) {
-#define V(name, _) &Environment::name,
- static Local<Private> (Environment::*const methods[])() const = {
- PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
- };
-#undef V
- CHECK_LT(index, arraysize(methods));
- return (env->*methods[index])();
-}
-
-static void GetHiddenValue(const FunctionCallbackInfo<Value>& args) {
- Environment* env = Environment::GetCurrent(args);
-
- CHECK(args[0]->IsObject());
- CHECK(args[1]->IsUint32());
-
- Local<Object> obj = args[0].As<Object>();
- uint32_t index = args[1].As<Uint32>()->Value();
- Local<Private> private_symbol = IndexToPrivateSymbol(env, index);
- Local<Value> ret;
- if (obj->GetPrivate(env->context(), private_symbol).ToLocal(&ret))
- args.GetReturnValue().Set(ret);
-}
-
-static void SetHiddenValue(const FunctionCallbackInfo<Value>& args) {
- Environment* env = Environment::GetCurrent(args);
-
- CHECK(args[0]->IsObject());
- CHECK(args[1]->IsUint32());
-
- Local<Object> obj = args[0].As<Object>();
- uint32_t index = args[1].As<Uint32>()->Value();
- Local<Private> private_symbol = IndexToPrivateSymbol(env, index);
- bool ret;
- if (obj->SetPrivate(env->context(), private_symbol, args[2]).To(&ret))
- args.GetReturnValue().Set(ret);
-}
-
static void Sleep(const FunctionCallbackInfo<Value>& args) {
CHECK(args[0]->IsUint32());
uint32_t msec = args[0].As<Uint32>()->Value();
@@ -386,8 +347,6 @@ static void ToUSVString(const FunctionCallbackInfo<Value>& args) {
}
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
- registry->Register(GetHiddenValue);
- registry->Register(SetHiddenValue);
registry->Register(GetPromiseDetails);
registry->Register(GetProxyDetails);
registry->Register(PreviewEntries);
@@ -412,16 +371,22 @@ void Initialize(Local<Object> target,
Environment* env = Environment::GetCurrent(context);
Isolate* isolate = env->isolate();
-#define V(name, _) \
- target->Set(context, \
- FIXED_ONE_BYTE_STRING(env->isolate(), #name), \
- Integer::NewFromUnsigned(env->isolate(), index++)).Check();
{
- uint32_t index = 0;
+ Local<v8::ObjectTemplate> tmpl = v8::ObjectTemplate::New(isolate);
+#define V(PropertyName, _) \
+ tmpl->Set(FIXED_ONE_BYTE_STRING(env->isolate(), #PropertyName), \
+ env->PropertyName());
+
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
- }
#undef V
+ target
+ ->Set(context,
+ FIXED_ONE_BYTE_STRING(isolate, "privateSymbols"),
+ tmpl->NewInstance(context).ToLocalChecked())
+ .Check();
+ }
+
#define V(name) \
target->Set(context, \
FIXED_ONE_BYTE_STRING(env->isolate(), #name), \
@@ -432,8 +397,6 @@ void Initialize(Local<Object> target,
V(kRejected);
#undef V
- SetMethodNoSideEffect(context, target, "getHiddenValue", GetHiddenValue);
- SetMethod(context, target, "setHiddenValue", SetHiddenValue);
SetMethodNoSideEffect(
context, target, "getPromiseDetails", GetPromiseDetails);
SetMethodNoSideEffect(context, target, "getProxyDetails", GetProxyDetails);
diff --git a/test/parallel/test-internal-util-decorate-error-stack.js b/test/parallel/test-internal-util-decorate-error-stack.js
index b36714b44b..3566d9375f 100644
--- a/test/parallel/test-internal-util-decorate-error-stack.js
+++ b/test/parallel/test-internal-util-decorate-error-stack.js
@@ -5,12 +5,14 @@ const fixtures = require('../common/fixtures');
const assert = require('assert');
const internalUtil = require('internal/util');
const { internalBinding } = require('internal/test/binding');
-const binding = internalBinding('util');
+const {
+ privateSymbols: {
+ arrow_message_private_symbol,
+ decorated_private_symbol,
+ }
+} = internalBinding('util');
const spawnSync = require('child_process').spawnSync;
-const kArrowMessagePrivateSymbolIndex = binding.arrow_message_private_symbol;
-const kDecoratedPrivateSymbolIndex = binding.decorated_private_symbol;
-
const decorateErrorStack = internalUtil.decorateErrorStack;
// Verify that decorateErrorStack does not throw with non-objects.
@@ -73,9 +75,8 @@ const arrowMessage = 'arrow_message';
err = new Error('foo');
originalStack = err.stack;
-binding.setHiddenValue(err, kArrowMessagePrivateSymbolIndex, arrowMessage);
+err[arrow_message_private_symbol] = arrowMessage;
decorateErrorStack(err);
assert.strictEqual(err.stack, `${arrowMessage}${originalStack}`);
-assert.strictEqual(
- binding.getHiddenValue(err, kDecoratedPrivateSymbolIndex), true);
+assert.strictEqual(err[decorated_private_symbol], true);
diff --git a/test/parallel/test-util-internal.js b/test/parallel/test-util-internal.js
index 36d65e54d5..e2b500daa7 100644
--- a/test/parallel/test-util-internal.js
+++ b/test/parallel/test-util-internal.js
@@ -7,30 +7,24 @@ const fixtures = require('../common/fixtures');
const { internalBinding } = require('internal/test/binding');
const {
- getHiddenValue,
- setHiddenValue,
- arrow_message_private_symbol: kArrowMessagePrivateSymbolIndex
+ privateSymbols: {
+ arrow_message_private_symbol,
+ },
} = internalBinding('util');
-assert.strictEqual(
- getHiddenValue({}, kArrowMessagePrivateSymbolIndex),
- undefined);
-
const obj = {};
-assert.strictEqual(
- setHiddenValue(obj, kArrowMessagePrivateSymbolIndex, 'bar'),
- true);
-assert.strictEqual(
- getHiddenValue(obj, kArrowMessagePrivateSymbolIndex),
- 'bar');
+assert.strictEqual(obj[arrow_message_private_symbol], undefined);
+
+obj[arrow_message_private_symbol] = 'bar';
+assert.strictEqual(obj[arrow_message_private_symbol], 'bar');
+assert.deepStrictEqual(Reflect.ownKeys(obj), []);
let arrowMessage;
try {
require(fixtures.path('syntax', 'bad_syntax'));
} catch (err) {
- arrowMessage =
- getHiddenValue(err, kArrowMessagePrivateSymbolIndex);
+ arrowMessage = err[arrow_message_private_symbol];
}
assert.match(arrowMessage, /bad_syntax\.js:1/);