Skip to content

node-api: add napi_create_external_sharedarraybuffer#62623

Open
bnoordhuis wants to merge 5 commits intonodejs:mainfrom
bnoordhuis:fix62259
Open

node-api: add napi_create_external_sharedarraybuffer#62623
bnoordhuis wants to merge 5 commits intonodejs:mainfrom
bnoordhuis:fix62259

Conversation

@bnoordhuis
Copy link
Copy Markdown
Member

Creates a SharedArrayBuffer from externally managed memory.

Fixes: #62259

Creates a SharedArrayBuffer from externally managed memory.

Fixes: nodejs#62259
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/node-api

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. node-api Issues and PRs related to the Node-API. labels Apr 7, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 7, 2026

Codecov Report

❌ Patch coverage is 80.76923% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.78%. Comparing base (f48ac91) to head (5d2dd37).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
src/js_native_api_v8.cc 80.76% 0 Missing and 5 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #62623      +/-   ##
==========================================
+ Coverage   89.77%   89.78%   +0.01%     
==========================================
  Files         697      697              
  Lines      215749   215775      +26     
  Branches    41304    41295       -9     
==========================================
+ Hits       193681   193740      +59     
+ Misses      14161    14121      -40     
- Partials     7907     7914       +7     
Files with missing lines Coverage Δ
src/js_native_api_v8.cc 76.54% <80.76%> (+0.05%) ⬆️

... and 29 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@ronag ronag added the request-ci Add this label to start a Jenkins CI on a PR. label Apr 7, 2026
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Apr 7, 2026
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

@ronag ronag added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Apr 7, 2026
@ronag ronag requested a review from vmoroz April 7, 2026 14:16
node_api_basic_finalize finalize_cb,
void* finalize_hint,
napi_value* result);
NAPI_EXTERN napi_status NAPI_CDECL napi_create_external_sharedarraybuffer(
Copy link
Copy Markdown
Member

@legendecas legendecas Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be an experimental API first.

Suggested change
NAPI_EXTERN napi_status NAPI_CDECL napi_create_external_sharedarraybuffer(
#ifdef NAPI_EXPERIMENTAL
#define NODE_API_EXPERIMENTAL_HAS_CREATE_EXTERNAL_SHAREDARRAYBUFFER
NAPI_EXTERN napi_status NAPI_CDECL napi_create_external_sharedarraybuffer(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the macro be NODE_API_EXPERIMENTAL_HAS_CREATE_EXTERNAL_SHAREDARRAYBUFFER?

global.gc();
await tick(10);
console.log('gc3');
assert.strictEqual(binding.getDeleterCallCount(), 3);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use const { gcUntil } = require('../../common/gc')? It would be more stable in tests on GC..


<!-- YAML
added: REPLACEME
napiVersion: 1
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be an experimental API first.

Suggested change
napiVersion: 1

Create a `SharedArrayBuffer` with externally managed memory.

See the entry on [`napi_create_external_arraybuffer`][] for runtime
compatibility.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a difference worth pointing out here is that the finalizer in napi_create_external_arraybuffer will be invoked on the JS thread. But this finalize_cb could be invoked on an arbitrary thread.

@legendecas legendecas removed the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Apr 7, 2026
@legendecas legendecas moved this from Need Triage to In Progress in Node-API Team Project Apr 7, 2026
node_api_basic_finalize finalize_cb,
void* finalize_hint,
napi_value* result);
NAPI_EXTERN napi_status NAPI_CDECL napi_create_external_sharedarraybuffer(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New Node-API functions should be prefixed with node_api_ and not napi_.

void (*finalize_cb)(void* external_data, void* finalize_hint),
void* finalize_hint,
napi_value* result) {
return v8impl::NewExternalSharedArrayBuffer(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this return napi_no_external_buffers_allowed if external buffers are not allowed, eg. when running in a sandboxed environment? Like napi_create_external_buffer does if V8_SANDBOX macro is defined.

JavaScript `ArrayBuffer`s are described in
[Section ArrayBuffer objects][] of the ECMAScript Language Specification.

#### `napi_create_external_sharedarraybuffer`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the node_api_ prefix for all node Node-API functions instead of napi_.

napi_env env,
void* external_data,
size_t byte_length,
void (*finalize_cb)(void* external_data, void* finalize_hint),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We typically do not use the inline function pointer types.
Can we use the node_api_basic_finalize here?
I guess it should OK to document there that env is null there.

return status;
}

napi_status NewExternalSharedArrayBuffer(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this implementation directly into the node_api_create_external_sharedarraybuffer. This is the pattern we use for all other Node-API functions. In practice it avoids having extra frame in the call stack when we debug code and unnecessary redirection.

auto shared_backing_store =
std::shared_ptr<v8::BackingStore>(std::move(unique_backing_store));
auto shared_array_buffer =
v8::SharedArrayBuffer::New(env->isolate, shared_backing_store);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add std::move for the shared_backing_store to avoid extra ref counter interlocked increment and decrement.

return status;
}

napi_status NewExternalSharedArrayBuffer(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure that the node_api_create_external_sharedarraybuffer has the typical set of parameter checks as we do for other Node-API functions.

if (finalize_cb != nullptr) {
deleter_data = new FinalizerData{finalize_cb, finalize_hint};
}
auto unique_backing_store = v8::SharedArrayBuffer::NewBackingStore(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to avoid auto for readability when possible.
IMHO, we should only use it for lambdas and iterators.
In other trivial cases like here using the real types can help readability and see the issues sooner like with the missing std::move below.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. node-api Issues and PRs related to the Node-API.

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

Missing napi_create_external_sharedarraybuffer

7 participants