mirror of
https://github.com/nodejs/node.git
synced 2025-12-28 07:50:41 +00:00
src: add internal binding for constructing SharedArrayBuffers
PR-URL: https://github.com/nodejs/node/pull/60497 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Shelley Vohr <shelley.vohr@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
parent
519c537875
commit
fdff838ce3
@ -225,10 +225,10 @@ export default [
|
||||
message: 'Use `const { ShadowRealm } = globalThis;` instead of the global.',
|
||||
},
|
||||
// SharedArrayBuffer is not available in primordials because it can be
|
||||
// disabled with --no-harmony-sharedarraybuffer CLI flag.
|
||||
// disabled with --enable-sharedarraybuffer-per-context CLI flag.
|
||||
{
|
||||
name: 'SharedArrayBuffer',
|
||||
message: 'Use `const { SharedArrayBuffer } = globalThis;` instead of the global.',
|
||||
message: "Use `const { constructSharedArrayBuffer } = require('internal/util');` instead of the global.",
|
||||
},
|
||||
{
|
||||
name: 'TextDecoder',
|
||||
|
||||
@ -59,6 +59,7 @@ const {
|
||||
} = require('internal/errors');
|
||||
const { signals } = internalBinding('constants').os;
|
||||
const {
|
||||
constructSharedArrayBuffer,
|
||||
guessHandleType: _guessHandleType,
|
||||
defineLazyProperties,
|
||||
privateSymbols: {
|
||||
@ -954,6 +955,7 @@ module.exports = {
|
||||
assertTypeScript,
|
||||
assignFunctionName,
|
||||
cachedResult,
|
||||
constructSharedArrayBuffer,
|
||||
convertToValidSignal,
|
||||
createClassWrapper,
|
||||
decorateErrorStack,
|
||||
|
||||
@ -10,6 +10,7 @@ namespace util {
|
||||
|
||||
using v8::ALL_PROPERTIES;
|
||||
using v8::Array;
|
||||
using v8::ArrayBuffer;
|
||||
using v8::ArrayBufferView;
|
||||
using v8::BigInt;
|
||||
using v8::Boolean;
|
||||
@ -34,6 +35,7 @@ using v8::ONLY_WRITABLE;
|
||||
using v8::Promise;
|
||||
using v8::PropertyFilter;
|
||||
using v8::Proxy;
|
||||
using v8::SharedArrayBuffer;
|
||||
using v8::SKIP_STRINGS;
|
||||
using v8::SKIP_SYMBOLS;
|
||||
using v8::StackFrame;
|
||||
@ -438,6 +440,30 @@ static void DefineLazyProperties(const FunctionCallbackInfo<Value>& args) {
|
||||
}
|
||||
}
|
||||
|
||||
void ConstructSharedArrayBuffer(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
int64_t length;
|
||||
// Note: IntegerValue() clamps its output, so excessively large input values
|
||||
// will not overflow
|
||||
if (!args[0]->IntegerValue(env->context()).To(&length)) {
|
||||
return;
|
||||
}
|
||||
if (length < 0 ||
|
||||
static_cast<uint64_t>(length) > ArrayBuffer::kMaxByteLength) {
|
||||
env->ThrowRangeError("Invalid array buffer length");
|
||||
return;
|
||||
}
|
||||
Local<SharedArrayBuffer> sab;
|
||||
if (!SharedArrayBuffer::MaybeNew(env->isolate(), static_cast<size_t>(length))
|
||||
.ToLocal(&sab)) {
|
||||
// Note: SharedArrayBuffer::MaybeNew doesn't schedule an exception if it
|
||||
// fails
|
||||
env->ThrowRangeError("Array buffer allocation failed");
|
||||
return;
|
||||
}
|
||||
args.GetReturnValue().Set(sab);
|
||||
}
|
||||
|
||||
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
|
||||
registry->Register(GetPromiseDetails);
|
||||
registry->Register(GetProxyDetails);
|
||||
@ -455,6 +481,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
|
||||
registry->Register(IsInsideNodeModules);
|
||||
registry->Register(DefineLazyProperties);
|
||||
registry->Register(DefineLazyPropertiesGetter);
|
||||
registry->Register(ConstructSharedArrayBuffer);
|
||||
}
|
||||
|
||||
void Initialize(Local<Object> target,
|
||||
@ -554,9 +581,12 @@ void Initialize(Local<Object> target,
|
||||
SetMethodNoSideEffect(context, target, "getCallSites", GetCallSites);
|
||||
SetMethod(context, target, "sleep", Sleep);
|
||||
SetMethod(context, target, "parseEnv", ParseEnv);
|
||||
|
||||
SetMethod(
|
||||
context, target, "arrayBufferViewHasBuffer", ArrayBufferViewHasBuffer);
|
||||
SetMethod(context,
|
||||
target,
|
||||
"constructSharedArrayBuffer",
|
||||
ConstructSharedArrayBuffer);
|
||||
|
||||
Local<String> should_abort_on_uncaught_toggle =
|
||||
FIXED_ONE_BYTE_STRING(env->isolate(), "shouldAbortOnUncaughtToggle");
|
||||
|
||||
18
test/parallel/test-internal-util-construct-sab.js
Normal file
18
test/parallel/test-internal-util-construct-sab.js
Normal file
@ -0,0 +1,18 @@
|
||||
// Flags: --enable-sharedarraybuffer-per-context --expose-internals
|
||||
'use strict';
|
||||
|
||||
require('../common');
|
||||
const assert = require('assert');
|
||||
const { isSharedArrayBuffer } = require('util/types');
|
||||
const { constructSharedArrayBuffer } = require('internal/util');
|
||||
|
||||
// We're testing that we can construct a SAB even when the global is not exposed.
|
||||
assert.strictEqual(typeof SharedArrayBuffer, 'undefined');
|
||||
|
||||
for (const length of [undefined, 0, 1, 2 ** 32]) {
|
||||
assert(isSharedArrayBuffer(constructSharedArrayBuffer(length)));
|
||||
}
|
||||
|
||||
for (const length of [-1, Number.MAX_SAFE_INTEGER + 1, 2 ** 64]) {
|
||||
assert.throws(() => constructSharedArrayBuffer(length), RangeError);
|
||||
}
|
||||
1
typings/internalBinding/util.d.ts
vendored
1
typings/internalBinding/util.d.ts
vendored
@ -46,6 +46,7 @@ export interface UtilBinding {
|
||||
parseEnv(content: string): Record<string, string>;
|
||||
styleText(format: Array<string> | string, text: string): string;
|
||||
isInsideNodeModules(frameLimit: number, defaultValue: unknown): boolean;
|
||||
constructSharedArrayBuffer(length?: number): SharedArrayBuffer;
|
||||
|
||||
constants: {
|
||||
kPending: 0;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user