Skip to content

Commit

Permalink
n-api: implement napi_is_detached_arraybuffer
Browse files Browse the repository at this point in the history
This implements ArrayBuffer#IsDetachedBuffer operation as per ECMAScript
specification Section 24.1.1.2 https://tc39.es/ecma262/#sec-isdetachedbuffer

Closes: nodejs#29955

Backport-PR-URL: nodejs#31422
PR-URL: nodejs#30613
Fixes: nodejs#29955
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: David Carlier <devnexen@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
  • Loading branch information
lundibundi committed Jan 20, 2020
1 parent 09e4182 commit 68afe9e
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 0 deletions.
26 changes: 26 additions & 0 deletions doc/api/n-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -3259,6 +3259,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
-->

> 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
Specification.

## Working with JavaScript Properties

N-API exposes a set of APIs to get and set properties on JavaScript
Expand Down Expand Up @@ -5272,6 +5297,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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
Expand Up @@ -3060,3 +3060,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() &&
value.As<v8::ArrayBuffer>()->GetContents().Data() == nullptr;

return napi_clear_last_error(env);
}
13 changes: 13 additions & 0 deletions test/js-native-api/test_typedarray/test.js
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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

0 comments on commit 68afe9e

Please sign in to comment.