GeezerVison is showing github.com — src: add internal binding for constructing SharedArrayBuffers · nodejs/node@fdff838
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/eslint.config_partial.mjs +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -225,10 +225,10 @@ export default [ | 225 | 225 | message: 'Use `const { ShadowRealm } = globalThis;` instead of the global.', | 226 | 226 | }, | 227 | 227 | // SharedArrayBuffer is not available in primordials because it can be | 228 | | - // disabled with --no-harmony-sharedarraybuffer CLI flag. | | 228 | + // disabled with --enable-sharedarraybuffer-per-context CLI flag. | 229 | 229 | { | 230 | 230 | name: 'SharedArrayBuffer', | 231 | | - message: 'Use `const { SharedArrayBuffer } = globalThis;` instead of the global.', | | 231 | + message: "Use `const { constructSharedArrayBuffer } = require('internal/util');` instead of the global.", | 232 | 232 | }, | 233 | 233 | { | 234 | 234 | name: 'TextDecoder', | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/util.js +2Lines changed: 2 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -59,6 +59,7 @@ const { | 59 | 59 | } = require('internal/errors'); | 60 | 60 | const { signals } = internalBinding('constants').os; | 61 | 61 | const { | | 62 | + constructSharedArrayBuffer, | 62 | 63 | guessHandleType: _guessHandleType, | 63 | 64 | defineLazyProperties, | 64 | 65 | privateSymbols: { | @@ -954,6 +955,7 @@ module.exports = { | 954 | 955 | assertTypeScript, | 955 | 956 | assignFunctionName, | 956 | 957 | cachedResult, | | 958 | + constructSharedArrayBuffer, | 957 | 959 | convertToValidSignal, | 958 | 960 | createClassWrapper, | 959 | 961 | decorateErrorStack, | |
Collapse file Copy file name to clipboardExpand all lines: src/node_util.cc +31-1Lines changed: 31 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -10,6 +10,7 @@ namespace util { | 10 | 10 |
| 11 | 11 | using v8::ALL_PROPERTIES; | 12 | 12 | using v8::Array; | | 13 | +using v8::ArrayBuffer; | 13 | 14 | using v8::ArrayBufferView; | 14 | 15 | using v8::BigInt; | 15 | 16 | using v8::Boolean; | @@ -34,6 +35,7 @@ using v8::ONLY_WRITABLE; | 34 | 35 | using v8::Promise; | 35 | 36 | using v8::PropertyFilter; | 36 | 37 | using v8::Proxy; | | 38 | +using v8::SharedArrayBuffer; | 37 | 39 | using v8::SKIP_STRINGS; | 38 | 40 | using v8::SKIP_SYMBOLS; | 39 | 41 | using v8::StackFrame; | @@ -438,6 +440,30 @@ static void DefineLazyProperties(const FunctionCallbackInfo<Value>& args) { | 438 | 440 | } | 439 | 441 | } | 440 | 442 |
| | 443 | +void ConstructSharedArrayBuffer(const FunctionCallbackInfo<Value>& args) { | | 444 | + Environment* env = Environment::GetCurrent(args); | | 445 | + int64_t length; | | 446 | + // Note: IntegerValue() clamps its output, so excessively large input values | | 447 | + // will not overflow | | 448 | + if (!args[0]->IntegerValue(env->context()).To(&length)) { | | 449 | + return; | | 450 | + } | | 451 | + if (length < 0 || | | 452 | + static_cast<uint64_t>(length) > ArrayBuffer::kMaxByteLength) { | | 453 | + env->ThrowRangeError("Invalid array buffer length"); | | 454 | + return; | | 455 | + } | | 456 | + Local<SharedArrayBuffer> sab; | | 457 | + if (!SharedArrayBuffer::MaybeNew(env->isolate(), static_cast<size_t>(length)) | | 458 | + .ToLocal(&sab)) { | | 459 | + // Note: SharedArrayBuffer::MaybeNew doesn't schedule an exception if it | | 460 | + // fails | | 461 | + env->ThrowRangeError("Array buffer allocation failed"); | | 462 | + return; | | 463 | + } | | 464 | + args.GetReturnValue().Set(sab); | | 465 | +} | | 466 | + | 441 | 467 | void RegisterExternalReferences(ExternalReferenceRegistry* registry) { | 442 | 468 | registry->Register(GetPromiseDetails); | 443 | 469 | registry->Register(GetProxyDetails); | @@ -455,6 +481,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { | 455 | 481 | registry->Register(IsInsideNodeModules); | 456 | 482 | registry->Register(DefineLazyProperties); | 457 | 483 | registry->Register(DefineLazyPropertiesGetter); | | 484 | + registry->Register(ConstructSharedArrayBuffer); | 458 | 485 | } | 459 | 486 |
| 460 | 487 | void Initialize(Local<Object> target, | @@ -554,9 +581,12 @@ void Initialize(Local<Object> target, | 554 | 581 | SetMethodNoSideEffect(context, target, "getCallSites", GetCallSites); | 555 | 582 | SetMethod(context, target, "sleep", Sleep); | 556 | 583 | SetMethod(context, target, "parseEnv", ParseEnv); | 557 | | - | 558 | 584 | SetMethod( | 559 | 585 | context, target, "arrayBufferViewHasBuffer", ArrayBufferViewHasBuffer); | | 586 | + SetMethod(context, | | 587 | + target, | | 588 | + "constructSharedArrayBuffer", | | 589 | + ConstructSharedArrayBuffer); | 560 | 590 |
| 561 | 591 | Local<String> should_abort_on_uncaught_toggle = | 562 | 592 | FIXED_ONE_BYTE_STRING(env->isolate(), "shouldAbortOnUncaughtToggle"); | |
Collapse file Copy file name to clipboard +18Lines changed: 18 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +// Flags: --enable-sharedarraybuffer-per-context --expose-internals | | 2 | +'use strict'; | | 3 | + | | 4 | +require('../common'); | | 5 | +const assert = require('assert'); | | 6 | +const { isSharedArrayBuffer } = require('util/types'); | | 7 | +const { constructSharedArrayBuffer } = require('internal/util'); | | 8 | + | | 9 | +// We're testing that we can construct a SAB even when the global is not exposed. | | 10 | +assert.strictEqual(typeof SharedArrayBuffer, 'undefined'); | | 11 | + | | 12 | +for (const length of [undefined, 0, 1, 2 ** 32]) { | | 13 | + assert(isSharedArrayBuffer(constructSharedArrayBuffer(length))); | | 14 | +} | | 15 | + | | 16 | +for (const length of [-1, Number.MAX_SAFE_INTEGER + 1, 2 ** 64]) { | | 17 | + assert.throws(() => constructSharedArrayBuffer(length), RangeError); | | 18 | +} |
Collapse file Copy file name to clipboardExpand all lines: typings/internalBinding/util.d.ts +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -46,6 +46,7 @@ export interface UtilBinding { | 46 | 46 | parseEnv(content: string): Record<string, string>; | 47 | 47 | styleText(format: Array<string> | string, text: string): string; | 48 | 48 | isInsideNodeModules(frameLimit: number, defaultValue: unknown): boolean; | | 49 | + constructSharedArrayBuffer(length?: number): SharedArrayBuffer; | 49 | 50 |
| 50 | 51 | constants: { | 51 | 52 | kPending: 0; | |
|