Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

napi: implement napi_is_detached_arraybuffer #30613

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 26 additions & 0 deletions doc/api/n-api.md
Expand Up @@ -3258,6 +3258,31 @@ that is, created with [`napi_create_external_arraybuffer`][].
This API represents the invocation of the `ArrayBuffer` detach operation as
defined in [Section 24.1.1.3][] of the ECMAScript Language Specification.

### napi_is_detached_arraybuffer
<!-- YAML
added: REPLACEME
-->

addaleax marked this conversation as resolved.
Show resolved Hide resolved
> Stability: 1 - Experimental

```C
napi_status napi_is_detached_arraybuffer(napi_env env,
napi_value arraybuffer,
bool* result)
```

* `[in] env`: The environment that the API is invoked under.
* `[in] arraybuffer`: The JavaScript `ArrayBuffer` to be checked.
* `[out] result`: Whether the `arraybuffer` is detached.

Returns `napi_ok` if the API succeeded.

The `ArrayBuffer` is considered detached if its internal data is `null`.

This API represents the invocation of the `ArrayBuffer` `IsDetachedBuffer`
operation as defined in [Section 24.1.1.2][] of the ECMAScript Language
Copy link
Member

Choose a reason for hiding this comment

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

section numbers tend to change, i'd just say "as defined in the ecmascript language specifiation."

Copy link
Member Author

Choose a reason for hiding this comment

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

This looks like a good idea but a lot of the other functions (in this doc) have links to the appropriate sections in the spec so I'm not sure.

Specification.

## Working with JavaScript Properties

N-API exposes a set of APIs to get and set properties on JavaScript
Expand Down Expand Up @@ -5259,6 +5284,7 @@ This API may only be called from the main thread.
[Section 7]: https://tc39.github.io/ecma262/#sec-abstract-operations
[Section 8.7]: https://tc39.es/ecma262/#sec-agents
[Section 9.1.6]: https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-defineownproperty-p-desc
[Section 24.1.1.2]: https://tc39.es/ecma262/#sec-isdetachedbuffer
[Travis CI]: https://travis-ci.org
[Visual Studio]: https://visualstudio.microsoft.com
[Working with JavaScript Properties]: #n_api_working_with_javascript_properties
Expand Down
4 changes: 4 additions & 0 deletions src/js_native_api.h
Expand Up @@ -518,6 +518,10 @@ NAPI_EXTERN napi_status napi_get_instance_data(napi_env env,
// ArrayBuffer detaching
NAPI_EXTERN napi_status napi_detach_arraybuffer(napi_env env,
napi_value arraybuffer);

NAPI_EXTERN napi_status napi_is_detached_arraybuffer(napi_env env,
napi_value value,
bool* result);
#endif // NAPI_EXPERIMENTAL

EXTERN_C_END
Expand Down
15 changes: 15 additions & 0 deletions src/js_native_api_v8.cc
Expand Up @@ -3039,3 +3039,18 @@ napi_status napi_detach_arraybuffer(napi_env env, napi_value arraybuffer) {

return napi_clear_last_error(env);
}

napi_status napi_is_detached_arraybuffer(napi_env env,
napi_value arraybuffer,
bool* result) {
CHECK_ENV(env);
CHECK_ARG(env, arraybuffer);
CHECK_ARG(env, result);

v8::Local<v8::Value> value = v8impl::V8LocalValueFromJsValue(arraybuffer);

*result = value->IsArrayBuffer() &&
legendecas marked this conversation as resolved.
Show resolved Hide resolved
value.As<v8::ArrayBuffer>()->GetBackingStore()->Data() == nullptr;

return napi_clear_last_error(env);
}
13 changes: 13 additions & 0 deletions test/js-native-api/test_typedarray/test.js
Expand Up @@ -87,8 +87,21 @@ arrayTypes.forEach((currentType) => {
assert.ok(externalResult instanceof Int8Array);
assert.strictEqual(externalResult.length, 3);
assert.strictEqual(externalResult.byteLength, 3);
assert.ok(!test_typedarray.IsDetached(buffer.buffer));
test_typedarray.Detach(buffer);
assert.ok(test_typedarray.IsDetached(buffer.buffer));
assert.ok(externalResult instanceof Int8Array);
assert.strictEqual(buffer.length, 0);
assert.strictEqual(buffer.byteLength, 0);
}

{
const buffer = new ArrayBuffer(128);
assert.ok(!test_typedarray.IsDetached(buffer));
}

{
const buffer = test_typedarray.NullArrayBuffer();
assert.ok(buffer instanceof ArrayBuffer);
assert.ok(test_typedarray.IsDetached(buffer));
}
32 changes: 32 additions & 0 deletions test/js-native-api/test_typedarray/test_typedarray.c
Expand Up @@ -97,6 +97,15 @@ static napi_value External(napi_env env, napi_callback_info info) {
return output_array;
}


static napi_value NullArrayBuffer(napi_env env, napi_callback_info info) {
static void* data = NULL;
napi_value arraybuffer;
NAPI_CALL(env,
napi_create_external_arraybuffer(env, data, 0, NULL, NULL, &arraybuffer));
return arraybuffer;
}

static napi_value CreateTypedArray(napi_env env, napi_callback_info info) {
size_t argc = 4;
napi_value args[4];
Expand Down Expand Up @@ -183,13 +192,36 @@ static napi_value Detach(napi_env env, napi_callback_info info) {
return NULL;
}

static napi_value IsDetached(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value args[1];
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
NAPI_ASSERT(env, argc == 1, "Wrong number of arguments.");

napi_value array_buffer = args[0];
bool is_arraybuffer;
NAPI_CALL(env, napi_is_arraybuffer(env, array_buffer, &is_arraybuffer));
NAPI_ASSERT(env, is_arraybuffer,
"Wrong type of arguments. Expects an array buffer as first argument.");

bool is_detached;
NAPI_CALL(env, napi_is_detached_arraybuffer(env, array_buffer, &is_detached));

napi_value result;
NAPI_CALL(env, napi_get_boolean(env, is_detached, &result));

return result;
}

EXTERN_C_START
napi_value Init(napi_env env, napi_value exports) {
napi_property_descriptor descriptors[] = {
DECLARE_NAPI_PROPERTY("Multiply", Multiply),
DECLARE_NAPI_PROPERTY("External", External),
DECLARE_NAPI_PROPERTY("NullArrayBuffer", NullArrayBuffer),
DECLARE_NAPI_PROPERTY("CreateTypedArray", CreateTypedArray),
DECLARE_NAPI_PROPERTY("Detach", Detach),
DECLARE_NAPI_PROPERTY("IsDetached", IsDetached),
};

NAPI_CALL(env, napi_define_properties(
Expand Down