diff --git a/CMakeLists.txt b/CMakeLists.txt index 32578ac..cf67540 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,8 +45,7 @@ function(add_node_api_cts_addon ADDON_NAME) endfunction() function(add_node_api_cts_experimental_addon ADDON_NAME) - cmake_parse_arguments(PARSE_ARGV 1 ARG "" "" "SOURCES") - add_node_api_cts_addon(${ADDON_NAME} ${ARG_SOURCES}) + add_node_api_cts_addon(${ADDON_NAME} ${ARGN}) target_compile_definitions(${ADDON_NAME} PRIVATE NAPI_EXPERIMENTAL) if(MSVC) target_link_libraries(${ADDON_NAME} PRIVATE ${NODE_API_EXPERIMENTAL_LIB}) diff --git a/PORTING.md b/PORTING.md index 657cbb3..4e64f35 100644 --- a/PORTING.md +++ b/PORTING.md @@ -68,7 +68,7 @@ Tests covering the engine-specific part of Node-API, defined in `js_native_api.h | `test_properties` | Ported ✅ | Easy | | `test_reference` | Not ported | Medium | | `test_reference_double_free` | Ported ✅ | Easy | -| `test_sharedarraybuffer` | Not ported | Medium | +| `test_sharedarraybuffer` | Ported ✅ | Medium | | `test_string` | Not ported | Medium | | `test_symbol` | Ported ✅ | Easy | | `test_typedarray` | Not ported | Medium | diff --git a/tests/js-native-api/test_sharedarraybuffer/CMakeLists.txt b/tests/js-native-api/test_sharedarraybuffer/CMakeLists.txt new file mode 100644 index 0000000..d9b8aba --- /dev/null +++ b/tests/js-native-api/test_sharedarraybuffer/CMakeLists.txt @@ -0,0 +1 @@ +add_node_api_cts_experimental_addon(test_sharedarraybuffer test_sharedarraybuffer.c) diff --git a/tests/js-native-api/test_sharedarraybuffer/test.js b/tests/js-native-api/test_sharedarraybuffer/test.js new file mode 100644 index 0000000..a8e50c9 --- /dev/null +++ b/tests/js-native-api/test_sharedarraybuffer/test.js @@ -0,0 +1,88 @@ +"use strict"; + +if (experimentalFeatures.sharedArrayBuffer) { + const test_sharedarraybuffer = loadAddon("test_sharedarraybuffer"); + + { + const sab = new SharedArrayBuffer(16); + const ab = new ArrayBuffer(16); + const obj = {}; + const arr = []; + + assert.strictEqual( + test_sharedarraybuffer.TestIsSharedArrayBuffer(sab), + true, + ); + assert.strictEqual( + test_sharedarraybuffer.TestIsSharedArrayBuffer(ab), + false, + ); + assert.strictEqual( + test_sharedarraybuffer.TestIsSharedArrayBuffer(obj), + false, + ); + assert.strictEqual( + test_sharedarraybuffer.TestIsSharedArrayBuffer(arr), + false, + ); + assert.strictEqual( + test_sharedarraybuffer.TestIsSharedArrayBuffer(null), + false, + ); + assert.strictEqual( + test_sharedarraybuffer.TestIsSharedArrayBuffer(undefined), + false, + ); + } + + // Test node_api_create_sharedarraybuffer + { + const sab = test_sharedarraybuffer.TestCreateSharedArrayBuffer(16); + assert(sab instanceof SharedArrayBuffer); + assert.strictEqual(sab.byteLength, 16); + } + + // Test node_api_create_get_sharedarraybuffer_info + { + const sab = new SharedArrayBuffer(32); + const byteLength = test_sharedarraybuffer.TestGetSharedArrayBufferInfo(sab); + assert.strictEqual(byteLength, 32); + } + + // Test data access + { + const sab = new SharedArrayBuffer(8); + const result = test_sharedarraybuffer.TestSharedArrayBufferData(sab); + assert.strictEqual(result, true); + + // Check if data was written correctly + const view = new Uint8Array(sab); + for (let i = 0; i < 8; i++) { + assert.strictEqual(view[i], i % 256); + } + } + + // Test data pointer from existing SharedArrayBuffer + { + const sab = new SharedArrayBuffer(16); + const result = test_sharedarraybuffer.TestSharedArrayBufferData(sab); + assert.strictEqual(result, true); + } + + // Test zero-length SharedArrayBuffer + { + const sab = test_sharedarraybuffer.TestCreateSharedArrayBuffer(0); + assert(sab instanceof SharedArrayBuffer); + assert.strictEqual(sab.byteLength, 0); + } + + // Test invalid arguments + { + assert.throws( + () => { + test_sharedarraybuffer.TestGetSharedArrayBufferInfo({}); + }, + { name: "Error", message: "Invalid argument" }, + ); + } +} diff --git a/tests/js-native-api/test_sharedarraybuffer/test_sharedarraybuffer.c b/tests/js-native-api/test_sharedarraybuffer/test_sharedarraybuffer.c new file mode 100644 index 0000000..661e52c --- /dev/null +++ b/tests/js-native-api/test_sharedarraybuffer/test_sharedarraybuffer.c @@ -0,0 +1,130 @@ +#define NAPI_EXPERIMENTAL +#include +#include +#include "../common.h" +#include "../entry_point.h" + +static napi_value TestIsSharedArrayBuffer(napi_env env, + napi_callback_info info) { + size_t argc = 1; + napi_value args[1]; + NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL)); + + NODE_API_ASSERT(env, argc >= 1, "Wrong number of arguments"); + + bool is_sharedarraybuffer; + NODE_API_CALL( + env, node_api_is_sharedarraybuffer(env, args[0], &is_sharedarraybuffer)); + + napi_value ret; + NODE_API_CALL(env, napi_get_boolean(env, is_sharedarraybuffer, &ret)); + + return ret; +} + +static napi_value TestCreateSharedArrayBuffer(napi_env env, + napi_callback_info info) { + size_t argc = 1; + napi_value args[1]; + NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL)); + + NODE_API_ASSERT(env, argc >= 1, "Wrong number of arguments"); + + napi_valuetype valuetype0; + NODE_API_CALL(env, napi_typeof(env, args[0], &valuetype0)); + + NODE_API_ASSERT( + env, + valuetype0 == napi_number, + "Wrong type of arguments. Expects a number as first argument."); + + int32_t byte_length; + NODE_API_CALL(env, napi_get_value_int32(env, args[0], &byte_length)); + + NODE_API_ASSERT(env, + byte_length >= 0, + "Invalid byte length. Expects a non-negative integer."); + + napi_value ret; + void* data; + NODE_API_CALL( + env, node_api_create_sharedarraybuffer(env, byte_length, &data, &ret)); + + return ret; +} + +static napi_value TestGetSharedArrayBufferInfo(napi_env env, + napi_callback_info info) { + size_t argc = 1; + napi_value args[1]; + NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL)); + + NODE_API_ASSERT(env, argc >= 1, "Wrong number of arguments"); + + void* data; + size_t byte_length; + NODE_API_CALL(env, + napi_get_arraybuffer_info(env, args[0], &data, &byte_length)); + + napi_value ret; + NODE_API_CALL(env, napi_create_uint32(env, byte_length, &ret)); + + return ret; +} + +static void WriteTestDataToBuffer(void* data, size_t byte_length) { + if (byte_length > 0 && data != NULL) { + uint8_t* bytes = (uint8_t*)data; + for (size_t i = 0; i < byte_length; i++) { + bytes[i] = i % 256; + } + } +} + +static napi_value TestSharedArrayBufferData(napi_env env, + napi_callback_info info) { + size_t argc = 1; + napi_value args[1]; + NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL)); + + NODE_API_ASSERT(env, argc >= 1, "Wrong number of arguments"); + + void* data; + size_t byte_length; + NODE_API_CALL(env, + napi_get_arraybuffer_info(env, args[0], &data, &byte_length)); + + WriteTestDataToBuffer(data, byte_length); + + // Return the same data pointer validity + bool data_valid = (data != NULL) && (byte_length > 0); + + napi_value ret; + NODE_API_CALL(env, napi_get_boolean(env, data_valid, &ret)); + + return ret; +} + +EXTERN_C_START +napi_value Init(napi_env env, napi_value exports) { + napi_property_descriptor descriptors[] = { + DECLARE_NODE_API_PROPERTY("TestIsSharedArrayBuffer", + TestIsSharedArrayBuffer), + DECLARE_NODE_API_PROPERTY("TestCreateSharedArrayBuffer", + TestCreateSharedArrayBuffer), + DECLARE_NODE_API_PROPERTY("TestGetSharedArrayBufferInfo", + TestGetSharedArrayBufferInfo), + DECLARE_NODE_API_PROPERTY("TestSharedArrayBufferData", + TestSharedArrayBufferData), + }; + + NODE_API_CALL( + env, + napi_define_properties(env, + exports, + sizeof(descriptors) / sizeof(*descriptors), + descriptors)); + + return exports; +} +EXTERN_C_END