GeezerVison is showing github.com — n-api: add `napi_detach_arraybuffer` · nodejs/node@961598b
File treeExpand file treeCollapse file tree Open diff view settings test/addons-napi/test_typedarray
Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: doc/api/n-api.md +27Lines changed: 27 additions & 0 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -265,6 +265,8 @@ typedef enum { | 265 | 265 | napi_closing, | 266 | 266 | napi_bigint_expected, | 267 | 267 | napi_date_expected, | | 268 | + napi_arraybuffer_expected, | | 269 | + napi_detachable_arraybuffer_expected, | 268 | 270 | } napi_status; | 269 | 271 | ``` | 270 | 272 | If additional information is required upon an API returning a failed status, | @@ -2946,6 +2948,30 @@ defined in | 2946 | 2948 | [Section 7.2.14](https://tc39.github.io/ecma262/#sec-strict-equality-comparison) | 2947 | 2949 | of the ECMAScript Language Specification. | 2948 | 2950 |
| | 2951 | +### napi_detach_arraybuffer | | 2952 | +<!-- YAML | | 2953 | +added: REPLACEME | | 2954 | +--> | | 2955 | + | | 2956 | +```C | | 2957 | +napi_status napi_detach_arraybuffer(napi_env env, | | 2958 | + napi_value arraybuffer) | | 2959 | +``` | | 2960 | + | | 2961 | +* `[in] env`: The environment that the API is invoked under. | | 2962 | +* `[in] arraybuffer`: The JavaScript `ArrayBuffer` to be detached. | | 2963 | + | | 2964 | +Returns `napi_ok` if the API succeeded. If a non-detachable `ArrayBuffer` is | | 2965 | +passed in it returns `napi_detachable_arraybuffer_expected`. | | 2966 | + | | 2967 | +Generally, an `ArrayBuffer` is non-detachable if it has been detached before. | | 2968 | +The engine may impose additional conditions on whether an `ArrayBuffer` is | | 2969 | +detachable. For example, V8 requires that the `ArrayBuffer` be external, | | 2970 | +that is, created with [`napi_create_external_arraybuffer`][]. | | 2971 | + | | 2972 | +This API represents the invocation of the `ArrayBuffer` detach operation as | | 2973 | +defined in [Section 24.1.1.3][] of the ECMAScript Language Specification. | | 2974 | + | 2949 | 2975 | ## Working with JavaScript Properties | 2950 | 2976 |
| 2951 | 2977 | N-API exposes a set of APIs to get and set properties on JavaScript | @@ -4889,6 +4915,7 @@ This API may only be called from the main thread. | 4889 | 4915 | [Section 22.1]: https://tc39.github.io/ecma262/#sec-array-objects | 4890 | 4916 | [Section 22.2]: https://tc39.github.io/ecma262/#sec-typedarray-objects | 4891 | 4917 | [Section 24.1]: https://tc39.github.io/ecma262/#sec-arraybuffer-objects | | 4918 | +[Section 24.1.1.3]: https://tc39.es/ecma262/#sec-detacharraybuffer | 4892 | 4919 | [Section 24.3]: https://tc39.github.io/ecma262/#sec-dataview-objects | 4893 | 4920 | [Section 25.4]: https://tc39.github.io/ecma262/#sec-promise-objects | 4894 | 4921 | [Section 6.1.4]: https://tc39.github.io/ecma262/#sec-ecmascript-language-types-string-type | |
Collapse file Copy file name to clipboardExpand all lines: src/node_api.cc +22-1Lines changed: 22 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -1386,6 +1386,8 @@ const char* error_messages[] = {nullptr, | 1386 | 1386 | "Thread-safe function handle is closing", | 1387 | 1387 | "A bigint was expected", | 1388 | 1388 | "A date was expected", | | 1389 | + "An arraybuffer was expected", | | 1390 | + "A detachable arraybuffer was expected", | 1389 | 1391 | }; | 1390 | 1392 |
| 1391 | 1393 | static inline napi_status napi_clear_last_error(napi_env env) { | @@ -1416,7 +1418,7 @@ napi_status napi_get_last_error_info(napi_env env, | 1416 | 1418 | // message in the `napi_status` enum each time a new error message is added. | 1417 | 1419 | // We don't have a napi_status_last as this would result in an ABI | 1418 | 1420 | // change each time a message was added. | 1419 | | - const int last_status = napi_date_expected; | | 1421 | + const int last_status = napi_detachable_arraybuffer_expected; | 1420 | 1422 |
| 1421 | 1423 | static_assert( | 1422 | 1424 | node::arraysize(error_messages) == last_status + 1, | @@ -4382,3 +4384,22 @@ napi_status napi_get_instance_data(napi_env env, | 4382 | 4384 |
| 4383 | 4385 | return napi_clear_last_error(env); | 4384 | 4386 | } | | 4387 | + | | 4388 | +napi_status napi_detach_arraybuffer(napi_env env, napi_value arraybuffer) { | | 4389 | + CHECK_ENV(env); | | 4390 | + CHECK_ARG(env, arraybuffer); | | 4391 | + | | 4392 | + v8::Local<v8::Value> value = v8impl::V8LocalValueFromJsValue(arraybuffer); | | 4393 | + RETURN_STATUS_IF_FALSE( | | 4394 | + env, value->IsArrayBuffer(), napi_arraybuffer_expected); | | 4395 | + | | 4396 | + v8::Local<v8::ArrayBuffer> it = value.As<v8::ArrayBuffer>(); | | 4397 | + RETURN_STATUS_IF_FALSE( | | 4398 | + env, it->IsExternal(), napi_detachable_arraybuffer_expected); | | 4399 | + RETURN_STATUS_IF_FALSE( | | 4400 | + env, it->IsNeuterable(), napi_detachable_arraybuffer_expected); | | 4401 | + | | 4402 | + it->Neuter(); | | 4403 | + | | 4404 | + return napi_clear_last_error(env); | | 4405 | +} |
Collapse file Copy file name to clipboardExpand all lines: src/node_api.h +7Lines changed: 7 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -747,6 +747,13 @@ napi_get_all_property_names(napi_env env, | 747 | 747 |
| 748 | 748 | #endif // NAPI_VERSION >= 6 | 749 | 749 |
| | 750 | +#ifdef NAPI_EXPERIMENTAL | | 751 | +// ArrayBuffer detaching | | 752 | +NAPI_EXTERN napi_status | | 753 | +napi_detach_arraybuffer(napi_env env, | | 754 | + napi_value arraybuffer); | | 755 | +#endif // NAPI_EXPERIMENTAL | | 756 | + | 750 | 757 | EXTERN_C_END | 751 | 758 |
| 752 | 759 | #endif // SRC_NODE_API_H_ |
Collapse file Copy file name to clipboardExpand all lines: src/node_api_types.h +2Lines changed: 2 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -83,6 +83,8 @@ typedef enum { | 83 | 83 | napi_closing, | 84 | 84 | napi_bigint_expected, | 85 | 85 | napi_date_expected, | | 86 | + napi_arraybuffer_expected, | | 87 | + napi_detachable_arraybuffer_expected, | 86 | 88 | } napi_status; | 87 | 89 | // Note: when adding a new enum value to `napi_status`, please also update | 88 | 90 | // `const int last_status` in `napi_get_last_error_info()' definition, | |
Collapse file Copy file name to clipboardExpand all lines: test/addons-napi/test_typedarray/test.js +18Lines changed: 18 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -74,3 +74,21 @@ nonByteArrayTypes.forEach((currentType) => { | 74 | 74 | console.log(`start of offset ${currentType}`); | 75 | 75 | }, RangeError); | 76 | 76 | }); | | 77 | + | | 78 | +// Test detaching | | 79 | +arrayTypes.forEach((currentType) => { | | 80 | + const buffer = Reflect.construct(currentType, [8]); | | 81 | + assert.throws( | | 82 | + () => test_typedarray.Detach(buffer), | | 83 | + /A detachable arraybuffer was expected/); | | 84 | +}); | | 85 | +{ | | 86 | + const buffer = test_typedarray.External(); | | 87 | + assert.ok(externalResult instanceof Int8Array); | | 88 | + assert.strictEqual(externalResult.length, 3); | | 89 | + assert.strictEqual(externalResult.byteLength, 3); | | 90 | + test_typedarray.Detach(buffer); | | 91 | + assert.ok(externalResult instanceof Int8Array); | | 92 | + assert.strictEqual(buffer.length, 0); | | 93 | + assert.strictEqual(buffer.byteLength, 0); | | 94 | +} |
Collapse file Copy file name to clipboardExpand all lines: test/addons-napi/test_typedarray/test_typedarray.c +19Lines changed: 19 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +#define NAPI_EXPERIMENTAL | 1 | 2 | #include <node_api.h> | 2 | 3 | #include <string.h> | 3 | 4 | #include "../common.h" | @@ -165,11 +166,29 @@ static napi_value CreateTypedArray(napi_env env, napi_callback_info info) { | 165 | 166 | return output_array; | 166 | 167 | } | 167 | 168 |
| | 169 | +static napi_value Detach(napi_env env, napi_callback_info info) { | | 170 | + size_t argc = 1; | | 171 | + napi_value args[1]; | | 172 | + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL)); | | 173 | + NAPI_ASSERT(env, argc == 1, "Wrong number of arguments."); | | 174 | + | | 175 | + bool is_typedarray; | | 176 | + NAPI_CALL(env, napi_is_typedarray(env, args[0], &is_typedarray)); | | 177 | + NAPI_ASSERT(env, is_typedarray, "Wrong type of arguments. Expects a typedarray as first argument."); | | 178 | + | | 179 | + napi_value arraybuffer; | | 180 | + NAPI_CALL(env, napi_get_typedarray_info(env, args[0], NULL, NULL, NULL, &arraybuffer, NULL)); | | 181 | + NAPI_CALL(env, napi_detach_arraybuffer(env, arraybuffer)); | | 182 | + | | 183 | + return NULL; | | 184 | +} | | 185 | + | 168 | 186 | static napi_value Init(napi_env env, napi_value exports) { | 169 | 187 | napi_property_descriptor descriptors[] = { | 170 | 188 | DECLARE_NAPI_PROPERTY("Multiply", Multiply), | 171 | 189 | DECLARE_NAPI_PROPERTY("External", External), | 172 | 190 | DECLARE_NAPI_PROPERTY("CreateTypedArray", CreateTypedArray), | | 191 | + DECLARE_NAPI_PROPERTY("Detach", Detach), | 173 | 192 | }; | 174 | 193 |
| 175 | 194 | NAPI_CALL(env, napi_define_properties( | |
|