From d6fca0c189219b6e97bc6fa2a5d1e6e7ec5a63cb Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Thu, 10 Jul 2025 12:02:04 +0200 Subject: [PATCH 01/14] Added node_api_impl files --- packages/host/android/CMakeLists.txt | 2 + packages/host/cpp/node_api_impl.cpp | 108 +++++++++++++++++++++++++++ packages/host/cpp/node_api_impl.hpp | 25 +++++++ 3 files changed, 135 insertions(+) create mode 100644 packages/host/cpp/node_api_impl.cpp create mode 100644 packages/host/cpp/node_api_impl.hpp diff --git a/packages/host/android/CMakeLists.txt b/packages/host/android/CMakeLists.txt index b913de7f..afafd9ef 100644 --- a/packages/host/android/CMakeLists.txt +++ b/packages/host/android/CMakeLists.txt @@ -20,6 +20,8 @@ add_library(node-api-host SHARED ../cpp/Logger.cpp ../cpp/CxxNodeApiHostModule.cpp ../cpp/WeakNodeApiInjector.cpp + ../cpp/node_api_impl.cpp + ../cpp/node_api_impl.hpp ) target_include_directories(node-api-host PRIVATE diff --git a/packages/host/cpp/node_api_impl.cpp b/packages/host/cpp/node_api_impl.cpp new file mode 100644 index 00000000..84660294 --- /dev/null +++ b/packages/host/cpp/node_api_impl.cpp @@ -0,0 +1,108 @@ +#include "node_api_impl.hpp" +#include "Logger.hpp" + +auto ArrayType = napi_uint8_array; + +napi_status NAPI_CDECL callstack::nodeapihost::napi_create_buffer( + napi_env env, size_t length, void** data, napi_value* result) { + napi_value buffer; + const auto status = napi_create_arraybuffer(env, length, data, &buffer); + if (status != napi_ok) { + return status; + } + + return napi_create_typedarray(env, ArrayType, length, buffer, 0, result); +} + +napi_status NAPI_CDECL callstack::nodeapihost::napi_create_buffer_copy( + napi_env env, + size_t length, + const void* data, + void** result_data, + napi_value* result) { + if (!length || !data || !result) { + return napi_invalid_arg; + } + + void* buffer = nullptr; + if (const auto status = ::napi_create_buffer(env, length, &buffer, result); + status != napi_ok) { + return status; + } + + std::memcpy(buffer, data, length); + return napi_ok; +} + +napi_status callstack::nodeapihost::napi_is_buffer( + napi_env env, napi_value value, bool* result) { + if (!result) { + return napi_invalid_arg; + } + + if (!value) { + *result = false; + return napi_ok; + } + + napi_valuetype type{}; + if (const auto status = napi_typeof(env, value, &type); status != napi_ok) { + return status; + } + + if (type != napi_object && type != napi_external) { + *result = false; + return napi_ok; + } + + auto isArrayBuffer{false}; + if (const auto status = napi_is_arraybuffer(env, value, &isArrayBuffer); + status != napi_ok) { + return status; + } + auto isTypedArray{false}; + if (const auto status = napi_is_typedarray(env, value, &isTypedArray); + status != napi_ok) { + return status; + } + + *result = isArrayBuffer || isTypedArray; + return napi_ok; +} + +napi_status callstack::nodeapihost::napi_get_buffer_info( + napi_env env, napi_value value, void** data, size_t* length) { + if (!data || !length) { + return napi_invalid_arg; + } + *data = nullptr; + *length = 0; + if (!value) { + return napi_ok; + } + + auto isArrayBuffer{false}; + if (const auto status = napi_is_arraybuffer(env, value, &isArrayBuffer); + status == napi_ok && isArrayBuffer) { + return napi_get_arraybuffer_info(env, value, data, length); + } + + auto isTypedArray{false}; + if (const auto status = napi_is_typedarray(env, value, &isTypedArray); + status == napi_ok && isTypedArray) { + return napi_get_typedarray_info( + env, value, &ArrayType, length, data, nullptr, nullptr); + } + + return napi_ok; +} + +napi_status callstack::nodeapihost::napi_create_external_buffer(napi_env env, + size_t length, + void* data, + node_api_basic_finalize basic_finalize_cb, + void* finalize_hint, + napi_value* result) { + return napi_create_external_arraybuffer( + env, data, length, basic_finalize_cb, finalize_hint, result); +} diff --git a/packages/host/cpp/node_api_impl.hpp b/packages/host/cpp/node_api_impl.hpp new file mode 100644 index 00000000..e64b03fa --- /dev/null +++ b/packages/host/cpp/node_api_impl.hpp @@ -0,0 +1,25 @@ +#include "node_api.h" + +namespace callstack::nodeapihost { +napi_status napi_create_buffer( + napi_env env, size_t length, void** data, napi_value* result); + +napi_status napi_create_buffer_copy(napi_env env, + size_t length, + const void* data, + void** result_data, + napi_value* result); + +napi_status napi_is_buffer(napi_env env, napi_value value, bool* result); + +napi_status napi_get_buffer_info( + napi_env env, napi_value value, void** data, size_t* length); + +napi_status napi_create_external_buffer(napi_env env, + size_t length, + void* data, + node_api_basic_finalize basic_finalize_cb, + void* finalize_hint, + napi_value* result); + +} // namespace callstack::nodeapihost From d2b6e492ca3703e9621a7a8d1c1acd21186fd17d Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Thu, 10 Jul 2025 12:06:12 +0200 Subject: [PATCH 02/14] Added test addon for buffers --- .../tests/buffers/.gitignore | 2 + .../tests/buffers/CMakeLists.txt | 16 + .../node-addon-examples/tests/buffers/addon.c | 335 +++++++++++ .../tests/buffers/addon.js | 37 ++ .../tests/buffers/binding.gyp | 8 + .../tests/buffers/package-lock.json | 540 ++++++++++++++++++ .../tests/buffers/package.json | 17 + 7 files changed, 955 insertions(+) create mode 100644 packages/node-addon-examples/tests/buffers/.gitignore create mode 100644 packages/node-addon-examples/tests/buffers/CMakeLists.txt create mode 100644 packages/node-addon-examples/tests/buffers/addon.c create mode 100644 packages/node-addon-examples/tests/buffers/addon.js create mode 100644 packages/node-addon-examples/tests/buffers/binding.gyp create mode 100644 packages/node-addon-examples/tests/buffers/package-lock.json create mode 100644 packages/node-addon-examples/tests/buffers/package.json diff --git a/packages/node-addon-examples/tests/buffers/.gitignore b/packages/node-addon-examples/tests/buffers/.gitignore new file mode 100644 index 00000000..44c5f4d8 --- /dev/null +++ b/packages/node-addon-examples/tests/buffers/.gitignore @@ -0,0 +1,2 @@ +build +*.node \ No newline at end of file diff --git a/packages/node-addon-examples/tests/buffers/CMakeLists.txt b/packages/node-addon-examples/tests/buffers/CMakeLists.txt new file mode 100644 index 00000000..98d817c5 --- /dev/null +++ b/packages/node-addon-examples/tests/buffers/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.15) +project(test-buffers) +set(CMAKE_CXX_STANDARD 23) + +add_compile_definitions(NAPI_VERSION=8) + +add_library(addon SHARED addon.c ${CMAKE_JS_SRC}) +set_target_properties(addon PROPERTIES PREFIX "" SUFFIX ".node") +target_include_directories(addon PRIVATE ${CMAKE_JS_INC}) +target_link_libraries(addon PRIVATE ${CMAKE_JS_LIB}) +target_compile_features(addon PRIVATE cxx_std_17) + +if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET) + # Generate node.lib + execute_process(COMMAND ${CMAKE_AR} /def:${CMAKE_JS_NODELIB_DEF} /out:${CMAKE_JS_NODELIB_TARGET} ${CMAKE_STATIC_LINKER_FLAGS}) +endif() \ No newline at end of file diff --git a/packages/node-addon-examples/tests/buffers/addon.c b/packages/node-addon-examples/tests/buffers/addon.c new file mode 100644 index 00000000..14c89d74 --- /dev/null +++ b/packages/node-addon-examples/tests/buffers/addon.c @@ -0,0 +1,335 @@ +#include +#include +#include +#include +// #include "../../js-native-api/common.h" + +#define NODE_API_RETVAL_NOTHING // Intentionally blank #define + +#define GET_AND_THROW_LAST_ERROR(env) \ + do { \ + const napi_extended_error_info* error_info; \ + napi_get_last_error_info((env), &error_info); \ + bool is_pending; \ + const char* err_message = error_info->error_message; \ + napi_is_exception_pending((env), &is_pending); \ + /* If an exception is already pending, don't rethrow it */ \ + if (!is_pending) { \ + const char* error_message = \ + err_message != NULL ? err_message : "empty error message"; \ + napi_throw_error((env), NULL, error_message); \ + } \ + } while (0) + +// The basic version of GET_AND_THROW_LAST_ERROR. We cannot access any +// exceptions and we cannot fail by way of JS exception, so we abort. +#define FATALLY_FAIL_WITH_LAST_ERROR(env) \ + do { \ + const napi_extended_error_info* error_info; \ + napi_get_last_error_info((env), &error_info); \ + const char* err_message = error_info->error_message; \ + const char* error_message = \ + err_message != NULL ? err_message : "empty error message"; \ + fprintf(stderr, "%s\n", error_message); \ + abort(); \ + } while (0) + +#define NODE_API_ASSERT_BASE(env, assertion, message, ret_val) \ + do { \ + if (!(assertion)) { \ + napi_throw_error( \ + (env), NULL, "assertion (" #assertion ") failed: " message); \ + return ret_val; \ + } \ + } while (0) + +#define NODE_API_BASIC_ASSERT_BASE(assertion, message, ret_val) \ + do { \ + if (!(assertion)) { \ + fprintf(stderr, "assertion (" #assertion ") failed: " message); \ + abort(); \ + return ret_val; \ + } \ + } while (0) + +// Returns NULL on failed assertion. +// This is meant to be used inside napi_callback methods. +#define NODE_API_ASSERT(env, assertion, message) \ + NODE_API_ASSERT_BASE(env, assertion, message, NULL) + +// Returns empty on failed assertion. +// This is meant to be used inside functions with void return type. +#define NODE_API_ASSERT_RETURN_VOID(env, assertion, message) \ + NODE_API_ASSERT_BASE(env, assertion, message, NODE_API_RETVAL_NOTHING) + +#define NODE_API_BASIC_ASSERT_RETURN_VOID(assertion, message) \ + NODE_API_BASIC_ASSERT_BASE(assertion, message, NODE_API_RETVAL_NOTHING) + +#define NODE_API_CALL_BASE(env, the_call, ret_val) \ + do { \ + if ((the_call) != napi_ok) { \ + GET_AND_THROW_LAST_ERROR((env)); \ + return ret_val; \ + } \ + } while (0) + +#define NODE_API_BASIC_CALL_BASE(env, the_call, ret_val) \ + do { \ + if ((the_call) != napi_ok) { \ + FATALLY_FAIL_WITH_LAST_ERROR((env)); \ + return ret_val; \ + } \ + } while (0) + +// Returns NULL if the_call doesn't return napi_ok. +#define NODE_API_CALL(env, the_call) NODE_API_CALL_BASE(env, the_call, NULL) + +// Returns empty if the_call doesn't return napi_ok. +#define NODE_API_CALL_RETURN_VOID(env, the_call) \ + NODE_API_CALL_BASE(env, the_call, NODE_API_RETVAL_NOTHING) + +#define NODE_API_BASIC_CALL_RETURN_VOID(env, the_call) \ + NODE_API_BASIC_CALL_BASE(env, the_call, NODE_API_RETVAL_NOTHING) + +#define NODE_API_CHECK_STATUS(the_call) \ + do { \ + napi_status status = (the_call); \ + if (status != napi_ok) { \ + return status; \ + } \ + } while (0) + +#define NODE_API_ASSERT_STATUS(env, assertion, message) \ + NODE_API_ASSERT_BASE(env, assertion, message, napi_generic_failure) + +#define DECLARE_NODE_API_PROPERTY(name, func) \ + {(name), NULL, (func), NULL, NULL, NULL, napi_default, NULL} + +#define DECLARE_NODE_API_GETTER(name, func) \ + {(name), NULL, NULL, (func), NULL, NULL, napi_default, NULL} + +#define DECLARE_NODE_API_PROPERTY_VALUE(name, value) \ + {(name), NULL, NULL, NULL, NULL, (value), napi_default, NULL} + +static inline void add_returned_status(napi_env env, + const char* key, + napi_value object, + char* expected_message, + napi_status expected_status, + napi_status actual_status); + +static inline void add_last_status( + napi_env env, const char* key, napi_value return_value); + +static const char theText[] = + "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; + +static int deleterCallCount = 0; + +static void deleteTheText( + node_api_basic_env env, void* data, void* finalize_hint) { + NODE_API_BASIC_ASSERT_RETURN_VOID( + data != NULL && strcmp(data, theText) == 0, "invalid data"); + + printf("XDDDD"); + (void)finalize_hint; + free(data); + deleterCallCount++; +} + +static void noopDeleter( + node_api_basic_env env, void* data, void* finalize_hint) { + NODE_API_BASIC_ASSERT_RETURN_VOID( + data != NULL && strcmp(data, theText) == 0, "invalid data"); + (void)finalize_hint; + deleterCallCount++; +} + +static napi_value newBuffer(napi_env env, napi_callback_info info) { + napi_value theBuffer; + char* theCopy; + const unsigned int kBufferSize = sizeof(theText); + + NODE_API_CALL(env, + napi_create_buffer(env, sizeof(theText), (void**)(&theCopy), &theBuffer)); + NODE_API_ASSERT(env, theCopy, "Failed to copy static text for newBuffer"); + memcpy(theCopy, theText, kBufferSize); + + return theBuffer; + + // napi_value theBuffer, result; + // char* theCopy; + // const unsigned int kBufferSize = sizeof(theText); + + // napi_status status = + // napi_create_arraybuffer(env, kBufferSize, (void**)(&theCopy), + // &theBuffer); + // if (status != napi_ok) { + // printf("Failed to create arraybuffer\n"); + // return NULL; + // } + + // memcpy(theCopy, theText, kBufferSize); + + // napi_typedarray_type arrayType = napi_uint8_array; + // status = napi_create_typedarray( + // env, arrayType, kBufferSize, theBuffer, 0, &result); + // if (status != napi_ok) { + // printf("Failed to create typedarray\n"); + // return NULL; + // } + // return result; +} + +static napi_value newExternalBuffer(napi_env env, napi_callback_info info) { + printf("creating external buffer\n"); + napi_value theBuffer; + char* theCopy = strdup(theText); + NODE_API_ASSERT( + env, theCopy, "Failed to copy static text for newExternalBuffer"); + NODE_API_CALL(env, + napi_create_external_buffer(env, + sizeof(theText), + theCopy, + deleteTheText, + NULL /* finalize_hint */, + &theBuffer)); + + return theBuffer; +} + +static napi_value getDeleterCallCount(napi_env env, napi_callback_info info) { + napi_value callCount; + NODE_API_CALL(env, napi_create_int32(env, deleterCallCount, &callCount)); + return callCount; +} + +static napi_value copyBuffer(napi_env env, napi_callback_info info) { + napi_value theBuffer; + NODE_API_CALL(env, + napi_create_buffer_copy(env, sizeof(theText), theText, NULL, &theBuffer)); + return theBuffer; +} + +static napi_value bufferHasInstance(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_value theBuffer = args[0]; + bool hasInstance; + napi_valuetype theType; + NODE_API_CALL(env, napi_typeof(env, theBuffer, &theType)); + NODE_API_ASSERT(env, + theType == napi_object, + "bufferHasInstance: instance is not an object"); + NODE_API_CALL(env, napi_is_buffer(env, theBuffer, &hasInstance)); + NODE_API_ASSERT( + env, hasInstance, "bufferHasInstance: instance is not a buffer"); + napi_value returnValue; + NODE_API_CALL(env, napi_get_boolean(env, hasInstance, &returnValue)); + return returnValue; +} + +static napi_value bufferInfo(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_value theBuffer = args[0]; + char* bufferData; + napi_value returnValue; + size_t bufferLength; + NODE_API_CALL(env, + napi_get_buffer_info( + env, theBuffer, (void**)(&bufferData), &bufferLength)); + NODE_API_CALL(env, + napi_get_boolean(env, + !strcmp(bufferData, theText) && bufferLength == sizeof(theText), + &returnValue)); + return returnValue; +} + +static napi_value staticBuffer(napi_env env, napi_callback_info info) { + napi_value theBuffer; + NODE_API_CALL(env, + napi_create_external_buffer(env, + sizeof(theText), + (void*)theText, + noopDeleter, + NULL /* finalize_hint */, + &theBuffer)); + return theBuffer; +} + +static napi_value invalidObjectAsBuffer(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_value notTheBuffer = args[0]; + napi_status status = napi_get_buffer_info(env, notTheBuffer, NULL, NULL); + NODE_API_ASSERT(env, + status == napi_invalid_arg, + "napi_get_buffer_info: should fail with napi_invalid_arg " + "when passed non buffer"); + + return notTheBuffer; +} + +static napi_value bufferFromArrayBuffer(napi_env env, napi_callback_info info) { + napi_status status; + napi_value arraybuffer; + napi_value buffer; + size_t byte_length = 1024; + void* data = NULL; + size_t buffer_length = 0; + void* buffer_data = NULL; + + status = napi_create_arraybuffer(env, byte_length, &data, &arraybuffer); + NODE_API_ASSERT(env, status == napi_ok, "Failed to create arraybuffer"); + +#if NAPI_VERSION >= 10 + status = node_api_create_buffer_from_arraybuffer( + env, arraybuffer, 0, byte_length, &buffer); + NODE_API_ASSERT( + env, status == napi_ok, "Failed to create buffer from arraybuffer"); +#endif + + status = napi_get_buffer_info(env, buffer, &buffer_data, &buffer_length); + NODE_API_ASSERT(env, status == napi_ok, "Failed to get buffer info"); + + NODE_API_ASSERT(env, buffer_length == byte_length, "Buffer length mismatch"); + + return buffer; +} + +static napi_value Init(napi_env env, napi_value exports) { + napi_value theValue; + + NODE_API_CALL( + env, napi_create_string_utf8(env, theText, sizeof(theText), &theValue)); + NODE_API_CALL( + env, napi_set_named_property(env, exports, "theText", theValue)); + + napi_property_descriptor methods[] = { + DECLARE_NODE_API_PROPERTY("newBuffer", newBuffer), + DECLARE_NODE_API_PROPERTY("newExternalBuffer", newExternalBuffer), + DECLARE_NODE_API_PROPERTY("getDeleterCallCount", getDeleterCallCount), + DECLARE_NODE_API_PROPERTY("copyBuffer", copyBuffer), + DECLARE_NODE_API_PROPERTY("bufferHasInstance", bufferHasInstance), + DECLARE_NODE_API_PROPERTY("bufferInfo", bufferInfo), + DECLARE_NODE_API_PROPERTY("staticBuffer", staticBuffer), + DECLARE_NODE_API_PROPERTY("invalidObjectAsBuffer", invalidObjectAsBuffer), + DECLARE_NODE_API_PROPERTY("bufferFromArrayBuffer", bufferFromArrayBuffer), + }; + + NODE_API_CALL(env, + napi_define_properties( + env, exports, sizeof(methods) / sizeof(methods[0]), methods)); + + return exports; +} + +NAPI_MODULE(NODE_GYP_MODULE_NAME, Init) \ No newline at end of file diff --git a/packages/node-addon-examples/tests/buffers/addon.js b/packages/node-addon-examples/tests/buffers/addon.js new file mode 100644 index 00000000..07ba0d68 --- /dev/null +++ b/packages/node-addon-examples/tests/buffers/addon.js @@ -0,0 +1,37 @@ +const addon = require('bindings')('addon') +const assert = require('assert'); + +const toLocaleString = (text) => { + return text.toLocaleString().split(',') + .map(code => String.fromCharCode(parseInt(code, 10))) + .join('');} + + +console.log(toLocaleString(addon.newExternalBuffer()), addon.theText); +// console.log(addon.newBuffer().toLocaleString(), addon.theText); + console.log('gc1'); + console.log(addon.getDeleterCallCount(), 0); + + global.gc(); + + console.log(addon.getDeleterCallCount(), 1); + +// console.log(addon.getDeleterCallCount(), 1); + // assert.strictEqual(addon.copyBuffer(), addon.theText); + +// let buffer = addon.staticBuffer(); +// assert.strictEqual(addon.bufferHasInstance(buffer), true); +// assert.strictEqual(addon.bufferInfo(buffer), true); +// buffer = null; +// global.gc(); +// console.log(addon.getDeleterCallCount(), 1); +// // await tick(10); +// console.log('gc2'); +// console.log(addon.getDeleterCallCount(), 2); + +// // // To test this doesn't crash +// addon.invalidObjectAsBuffer({}); + +// // const testBuffer = addon.bufferFromArrayBuffer(); +// // assert(testBuffer instanceof Buffer, 'Expected a Buffer'); +// // })().then(()=>{}); \ No newline at end of file diff --git a/packages/node-addon-examples/tests/buffers/binding.gyp b/packages/node-addon-examples/tests/buffers/binding.gyp new file mode 100644 index 00000000..80f9fa87 --- /dev/null +++ b/packages/node-addon-examples/tests/buffers/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "addon", + "sources": [ "addon.c" ] + } + ] +} diff --git a/packages/node-addon-examples/tests/buffers/package-lock.json b/packages/node-addon-examples/tests/buffers/package-lock.json new file mode 100644 index 00000000..2a66d127 --- /dev/null +++ b/packages/node-addon-examples/tests/buffers/package-lock.json @@ -0,0 +1,540 @@ +{ + "name": "buffers-test", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "buffers-tests", + "version": "0.0.0", + "dependencies": { + "assert": "^2.1.0", + "bindings": "~1.5.0" + } + }, + "node_modules/assert": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + } + } +} diff --git a/packages/node-addon-examples/tests/buffers/package.json b/packages/node-addon-examples/tests/buffers/package.json new file mode 100644 index 00000000..60b3e85d --- /dev/null +++ b/packages/node-addon-examples/tests/buffers/package.json @@ -0,0 +1,17 @@ +{ + "name": "buffers-test", + "version": "0.0.0", + "description": "Tests of runtime buffer functions", + "main": "addon.js", + "private": true, + "dependencies": { + "assert": "^2.1.0", + "bindings": "~1.5.0" + }, + "scripts": { + "test": "node --expose-gc addon.js" + }, + "gypfile": true, + "readme": "ERROR: No README data found!", + "_id": "function_arguments@0.0.0" +} From b74771bf08fc319b783e5e62132ae4c53fe7040b Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Thu, 10 Jul 2025 12:08:21 +0200 Subject: [PATCH 03/14] Injecting runtime functions --- .../scripts/generate-weak-node-api-injector.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/host/scripts/generate-weak-node-api-injector.ts b/packages/host/scripts/generate-weak-node-api-injector.ts index ff73b0ed..e1db9cfe 100644 --- a/packages/host/scripts/generate-weak-node-api-injector.ts +++ b/packages/host/scripts/generate-weak-node-api-injector.ts @@ -6,6 +6,15 @@ import { FunctionDecl, getNodeApiFunctions } from "./node-api-functions"; export const CPP_SOURCE_PATH = path.join(__dirname, "../cpp"); +// TODO: Remove when all runtime Node API functions are implemented +const implementedRuntimeFunctions = [ + "napi_create_buffer", + "napi_create_buffer_copy", + "napi_is_buffer", + "napi_get_buffer_info", + "napi_create_external_buffer", +]; + /** * Generates source code which injects the Node API functions from the host. */ @@ -15,7 +24,8 @@ export function generateSource(functions: FunctionDecl[]) { #include #include #include - + #include + #if defined(__APPLE__) #define WEAK_NODE_API_LIBRARY_NAME "@rpath/weak-node-api.framework/weak-node-api" #elif defined(__ANDROID__) @@ -43,7 +53,10 @@ export function generateSource(functions: FunctionDecl[]) { log_debug("Injecting WeakNodeApiHost"); inject_weak_node_api_host(WeakNodeApiHost { ${functions - .filter(({ kind }) => kind === "engine") + .filter( + ({ kind, name }) => + kind === "engine" || implementedRuntimeFunctions.includes(name) + ) .flatMap(({ name }) => `.${name} = ${name},`) .join("\n")} }); From a4d578e71ae81c920c8e70b4b7e07fd67814b750 Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Thu, 10 Jul 2025 12:08:48 +0200 Subject: [PATCH 04/14] Adjusting scripts --- packages/node-addon-examples/index.js | 5 ++++- packages/node-addon-examples/package.json | 2 +- .../node-addon-examples/scripts/cmake-projects.mts | 10 ++++++++-- .../node-addon-examples/tests/buffers/CMakeLists.txt | 2 +- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/node-addon-examples/index.js b/packages/node-addon-examples/index.js index 88470b76..8d5faecf 100644 --- a/packages/node-addon-examples/index.js +++ b/packages/node-addon-examples/index.js @@ -14,5 +14,8 @@ module.exports = { "5-async-work": { // TODO: This crashes (SIGABRT) // "async_work_thread_safe_function": () => require("./examples/5-async-work/async_work_thread_safe_function/napi/index.js"), - } + }, + "tests": { + "buffers": () => require("./tests/buffers/addon.js"), + }, }; diff --git a/packages/node-addon-examples/package.json b/packages/node-addon-examples/package.json index 835485c9..8960d63d 100644 --- a/packages/node-addon-examples/package.json +++ b/packages/node-addon-examples/package.json @@ -10,7 +10,7 @@ }, "scripts": { "copy-examples": "tsx scripts/copy-examples.mts", - "gyp-to-cmake": "gyp-to-cmake ./examples", + "gyp-to-cmake": "gyp-to-cmake .", "build": "tsx scripts/build-examples.mts", "copy-and-build": "npm run copy-examples && npm run gyp-to-cmake && npm run build", "verify": "tsx scripts/verify-prebuilds.mts", diff --git a/packages/node-addon-examples/scripts/cmake-projects.mts b/packages/node-addon-examples/scripts/cmake-projects.mts index a9d605f3..ede02e2c 100644 --- a/packages/node-addon-examples/scripts/cmake-projects.mts +++ b/packages/node-addon-examples/scripts/cmake-projects.mts @@ -2,15 +2,17 @@ import { readdirSync, statSync } from "node:fs"; import path from "node:path"; export const EXAMPLES_DIR = path.resolve(import.meta.dirname, "../examples"); +export const TESTS_DIR = path.resolve(import.meta.dirname, "../tests"); +export const DIRS = [EXAMPLES_DIR, TESTS_DIR]; -export function findCMakeProjects(dir = EXAMPLES_DIR): string[] { +export function findCMakeProjectsRecursively(dir): string[] { let results: string[] = []; const files = readdirSync(dir); for (const file of files) { const fullPath = path.join(dir, file); if (statSync(fullPath).isDirectory()) { - results = results.concat(findCMakeProjects(fullPath)); + results = results.concat(findCMakeProjectsRecursively(fullPath)); } else if (file === "CMakeLists.txt") { results.push(dir); } @@ -18,3 +20,7 @@ export function findCMakeProjects(dir = EXAMPLES_DIR): string[] { return results; } + +export function findCMakeProjects(): string[] { + return DIRS.flatMap(findCMakeProjectsRecursively); +} diff --git a/packages/node-addon-examples/tests/buffers/CMakeLists.txt b/packages/node-addon-examples/tests/buffers/CMakeLists.txt index 98d817c5..e6252230 100644 --- a/packages/node-addon-examples/tests/buffers/CMakeLists.txt +++ b/packages/node-addon-examples/tests/buffers/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.15) -project(test-buffers) +project(tests-buffers) set(CMAKE_CXX_STANDARD 23) add_compile_definitions(NAPI_VERSION=8) From f6b3f130896bac3b2bd4fa78d6f6bfc6c856e92c Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Thu, 10 Jul 2025 13:35:23 +0200 Subject: [PATCH 05/14] Buffer test updated --- .../tests/buffers/CMakeLists.txt | 1 - .../node-addon-examples/tests/buffers/addon.c | 52 ----------------- .../tests/buffers/addon.js | 58 ++++++++----------- 3 files changed, 25 insertions(+), 86 deletions(-) diff --git a/packages/node-addon-examples/tests/buffers/CMakeLists.txt b/packages/node-addon-examples/tests/buffers/CMakeLists.txt index e6252230..8e8cc950 100644 --- a/packages/node-addon-examples/tests/buffers/CMakeLists.txt +++ b/packages/node-addon-examples/tests/buffers/CMakeLists.txt @@ -1,6 +1,5 @@ cmake_minimum_required(VERSION 3.15) project(tests-buffers) -set(CMAKE_CXX_STANDARD 23) add_compile_definitions(NAPI_VERSION=8) diff --git a/packages/node-addon-examples/tests/buffers/addon.c b/packages/node-addon-examples/tests/buffers/addon.c index 14c89d74..1f229303 100644 --- a/packages/node-addon-examples/tests/buffers/addon.c +++ b/packages/node-addon-examples/tests/buffers/addon.c @@ -2,7 +2,6 @@ #include #include #include -// #include "../../js-native-api/common.h" #define NODE_API_RETVAL_NOTHING // Intentionally blank #define @@ -156,29 +155,6 @@ static napi_value newBuffer(napi_env env, napi_callback_info info) { memcpy(theCopy, theText, kBufferSize); return theBuffer; - - // napi_value theBuffer, result; - // char* theCopy; - // const unsigned int kBufferSize = sizeof(theText); - - // napi_status status = - // napi_create_arraybuffer(env, kBufferSize, (void**)(&theCopy), - // &theBuffer); - // if (status != napi_ok) { - // printf("Failed to create arraybuffer\n"); - // return NULL; - // } - - // memcpy(theCopy, theText, kBufferSize); - - // napi_typedarray_type arrayType = napi_uint8_array; - // status = napi_create_typedarray( - // env, arrayType, kBufferSize, theBuffer, 0, &result); - // if (status != napi_ok) { - // printf("Failed to create typedarray\n"); - // return NULL; - // } - // return result; } static napi_value newExternalBuffer(napi_env env, napi_callback_info info) { @@ -278,33 +254,6 @@ static napi_value invalidObjectAsBuffer(napi_env env, napi_callback_info info) { return notTheBuffer; } -static napi_value bufferFromArrayBuffer(napi_env env, napi_callback_info info) { - napi_status status; - napi_value arraybuffer; - napi_value buffer; - size_t byte_length = 1024; - void* data = NULL; - size_t buffer_length = 0; - void* buffer_data = NULL; - - status = napi_create_arraybuffer(env, byte_length, &data, &arraybuffer); - NODE_API_ASSERT(env, status == napi_ok, "Failed to create arraybuffer"); - -#if NAPI_VERSION >= 10 - status = node_api_create_buffer_from_arraybuffer( - env, arraybuffer, 0, byte_length, &buffer); - NODE_API_ASSERT( - env, status == napi_ok, "Failed to create buffer from arraybuffer"); -#endif - - status = napi_get_buffer_info(env, buffer, &buffer_data, &buffer_length); - NODE_API_ASSERT(env, status == napi_ok, "Failed to get buffer info"); - - NODE_API_ASSERT(env, buffer_length == byte_length, "Buffer length mismatch"); - - return buffer; -} - static napi_value Init(napi_env env, napi_value exports) { napi_value theValue; @@ -322,7 +271,6 @@ static napi_value Init(napi_env env, napi_value exports) { DECLARE_NODE_API_PROPERTY("bufferInfo", bufferInfo), DECLARE_NODE_API_PROPERTY("staticBuffer", staticBuffer), DECLARE_NODE_API_PROPERTY("invalidObjectAsBuffer", invalidObjectAsBuffer), - DECLARE_NODE_API_PROPERTY("bufferFromArrayBuffer", bufferFromArrayBuffer), }; NODE_API_CALL(env, diff --git a/packages/node-addon-examples/tests/buffers/addon.js b/packages/node-addon-examples/tests/buffers/addon.js index 07ba0d68..b56f897d 100644 --- a/packages/node-addon-examples/tests/buffers/addon.js +++ b/packages/node-addon-examples/tests/buffers/addon.js @@ -1,37 +1,29 @@ -const addon = require('bindings')('addon') -const assert = require('assert'); +const addon = require("bindings")("addon.node"); const toLocaleString = (text) => { - return text.toLocaleString().split(',') - .map(code => String.fromCharCode(parseInt(code, 10))) - .join('');} - + return text + .toLocaleString() + .split(",") + .map((code) => String.fromCharCode(parseInt(code, 10))) + .join(""); +}; console.log(toLocaleString(addon.newExternalBuffer()), addon.theText); -// console.log(addon.newBuffer().toLocaleString(), addon.theText); - console.log('gc1'); - console.log(addon.getDeleterCallCount(), 0); - - global.gc(); - - console.log(addon.getDeleterCallCount(), 1); - -// console.log(addon.getDeleterCallCount(), 1); - // assert.strictEqual(addon.copyBuffer(), addon.theText); - -// let buffer = addon.staticBuffer(); -// assert.strictEqual(addon.bufferHasInstance(buffer), true); -// assert.strictEqual(addon.bufferInfo(buffer), true); -// buffer = null; -// global.gc(); -// console.log(addon.getDeleterCallCount(), 1); -// // await tick(10); -// console.log('gc2'); -// console.log(addon.getDeleterCallCount(), 2); - -// // // To test this doesn't crash -// addon.invalidObjectAsBuffer({}); - -// // const testBuffer = addon.bufferFromArrayBuffer(); -// // assert(testBuffer instanceof Buffer, 'Expected a Buffer'); -// // })().then(()=>{}); \ No newline at end of file +console.log(addon.newBuffer().toLocaleString(), addon.theText); +console.log("gc1"); +console.log(addon.getDeleterCallCount(), 0); +global.gc(); +console.log(addon.getDeleterCallCount(), 1); +console.log(addon.getDeleterCallCount(), 1); +console.log(addon.copyBuffer(), addon.theText); + +let buffer = addon.staticBuffer(); +console.log(addon.bufferHasInstance(buffer), true); +console.log(addon.bufferInfo(buffer), true); +buffer = null; +global.gc(); +console.log(addon.getDeleterCallCount(), 1); +console.log("gc2"); +console.log(addon.getDeleterCallCount(), 2); + +addon.invalidObjectAsBuffer({}); From f868935e6afd2a235b1f114fd8a38ccf882aef19 Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Thu, 10 Jul 2025 14:10:33 +0200 Subject: [PATCH 06/14] Cleanup --- packages/host/cpp/node_api_impl.cpp | 2 +- .../tests/buffers/.gitignore | 1 - .../tests/buffers/CMakeLists.txt | 2 +- .../node-addon-examples/tests/buffers/addon.c | 2 +- .../tests/buffers/package-lock.json | 540 ------------------ .../tests/buffers/package.json | 1 - 6 files changed, 3 insertions(+), 545 deletions(-) delete mode 100644 packages/node-addon-examples/tests/buffers/package-lock.json diff --git a/packages/host/cpp/node_api_impl.cpp b/packages/host/cpp/node_api_impl.cpp index 84660294..173f9b29 100644 --- a/packages/host/cpp/node_api_impl.cpp +++ b/packages/host/cpp/node_api_impl.cpp @@ -1,5 +1,5 @@ #include "node_api_impl.hpp" -#include "Logger.hpp" +#include auto ArrayType = napi_uint8_array; diff --git a/packages/node-addon-examples/tests/buffers/.gitignore b/packages/node-addon-examples/tests/buffers/.gitignore index 44c5f4d8..378eac25 100644 --- a/packages/node-addon-examples/tests/buffers/.gitignore +++ b/packages/node-addon-examples/tests/buffers/.gitignore @@ -1,2 +1 @@ build -*.node \ No newline at end of file diff --git a/packages/node-addon-examples/tests/buffers/CMakeLists.txt b/packages/node-addon-examples/tests/buffers/CMakeLists.txt index 8e8cc950..7de25130 100644 --- a/packages/node-addon-examples/tests/buffers/CMakeLists.txt +++ b/packages/node-addon-examples/tests/buffers/CMakeLists.txt @@ -12,4 +12,4 @@ target_compile_features(addon PRIVATE cxx_std_17) if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET) # Generate node.lib execute_process(COMMAND ${CMAKE_AR} /def:${CMAKE_JS_NODELIB_DEF} /out:${CMAKE_JS_NODELIB_TARGET} ${CMAKE_STATIC_LINKER_FLAGS}) -endif() \ No newline at end of file +endif() diff --git a/packages/node-addon-examples/tests/buffers/addon.c b/packages/node-addon-examples/tests/buffers/addon.c index 1f229303..e153e726 100644 --- a/packages/node-addon-examples/tests/buffers/addon.c +++ b/packages/node-addon-examples/tests/buffers/addon.c @@ -280,4 +280,4 @@ static napi_value Init(napi_env env, napi_value exports) { return exports; } -NAPI_MODULE(NODE_GYP_MODULE_NAME, Init) \ No newline at end of file +NAPI_MODULE(NODE_GYP_MODULE_NAME, Init) diff --git a/packages/node-addon-examples/tests/buffers/package-lock.json b/packages/node-addon-examples/tests/buffers/package-lock.json deleted file mode 100644 index 2a66d127..00000000 --- a/packages/node-addon-examples/tests/buffers/package-lock.json +++ /dev/null @@ -1,540 +0,0 @@ -{ - "name": "buffers-test", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "buffers-tests", - "version": "0.0.0", - "dependencies": { - "assert": "^2.1.0", - "bindings": "~1.5.0" - } - }, - "node_modules/assert": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", - "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "is-nan": "^1.3.2", - "object-is": "^1.1.5", - "object.assign": "^4.1.4", - "util": "^0.12.5" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "license": "MIT", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "license": "MIT", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "license": "MIT" - }, - "node_modules/for-each": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", - "license": "MIT", - "dependencies": { - "is-callable": "^1.2.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/is-arguments": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", - "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-generator-function": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", - "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "get-proto": "^1.0.0", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-regex": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", - "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", - "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", - "license": "MIT", - "dependencies": { - "which-typed-array": "^1.1.16" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", - "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0", - "has-symbols": "^1.1.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", - "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/safe-regex-test": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", - "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-regex": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.19", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", - "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "for-each": "^0.3.5", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - } - } -} diff --git a/packages/node-addon-examples/tests/buffers/package.json b/packages/node-addon-examples/tests/buffers/package.json index 60b3e85d..1690df57 100644 --- a/packages/node-addon-examples/tests/buffers/package.json +++ b/packages/node-addon-examples/tests/buffers/package.json @@ -5,7 +5,6 @@ "main": "addon.js", "private": true, "dependencies": { - "assert": "^2.1.0", "bindings": "~1.5.0" }, "scripts": { From 82dd33b1c5db80ac8b08d027bc294a10d98537f1 Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Thu, 10 Jul 2025 14:21:49 +0200 Subject: [PATCH 07/14] Added eslint-disable for test addon --- packages/node-addon-examples/tests/buffers/addon.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/node-addon-examples/tests/buffers/addon.js b/packages/node-addon-examples/tests/buffers/addon.js index b56f897d..4f0f82a6 100644 --- a/packages/node-addon-examples/tests/buffers/addon.js +++ b/packages/node-addon-examples/tests/buffers/addon.js @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ +/* eslint-disable no-undef */ const addon = require("bindings")("addon.node"); const toLocaleString = (text) => { From 4db670ca8f3242304998f45622072e9a7e0e4ebf Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Thu, 10 Jul 2025 14:45:31 +0200 Subject: [PATCH 08/14] Removed debug lines --- packages/node-addon-examples/tests/buffers/addon.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/node-addon-examples/tests/buffers/addon.c b/packages/node-addon-examples/tests/buffers/addon.c index e153e726..2f83f681 100644 --- a/packages/node-addon-examples/tests/buffers/addon.c +++ b/packages/node-addon-examples/tests/buffers/addon.c @@ -130,7 +130,6 @@ static void deleteTheText( NODE_API_BASIC_ASSERT_RETURN_VOID( data != NULL && strcmp(data, theText) == 0, "invalid data"); - printf("XDDDD"); (void)finalize_hint; free(data); deleterCallCount++; @@ -158,7 +157,6 @@ static napi_value newBuffer(napi_env env, napi_callback_info info) { } static napi_value newExternalBuffer(napi_env env, napi_callback_info info) { - printf("creating external buffer\n"); napi_value theBuffer; char* theCopy = strdup(theText); NODE_API_ASSERT( From 4130877d9ea3153a7b54ecbfa337098a2ab07706 Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Fri, 11 Jul 2025 13:45:43 +0200 Subject: [PATCH 09/14] Moved .gitignore up --- packages/node-addon-examples/tests/{buffers => }/.gitignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/node-addon-examples/tests/{buffers => }/.gitignore (100%) diff --git a/packages/node-addon-examples/tests/buffers/.gitignore b/packages/node-addon-examples/tests/.gitignore similarity index 100% rename from packages/node-addon-examples/tests/buffers/.gitignore rename to packages/node-addon-examples/tests/.gitignore From 35f0b244722e5c9c41cea855045c84ae0349ad1f Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Fri, 11 Jul 2025 13:48:20 +0200 Subject: [PATCH 10/14] Renamed files to RuntimeNodeApi --- packages/host/android/CMakeLists.txt | 4 ++-- packages/host/cpp/{node_api_impl.cpp => RuntimeNodeApi.cpp} | 2 +- packages/host/cpp/{node_api_impl.hpp => RuntimeNodeApi.hpp} | 0 packages/host/scripts/generate-weak-node-api-injector.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename packages/host/cpp/{node_api_impl.cpp => RuntimeNodeApi.cpp} (98%) rename packages/host/cpp/{node_api_impl.hpp => RuntimeNodeApi.hpp} (100%) diff --git a/packages/host/android/CMakeLists.txt b/packages/host/android/CMakeLists.txt index afafd9ef..9fd1d22c 100644 --- a/packages/host/android/CMakeLists.txt +++ b/packages/host/android/CMakeLists.txt @@ -20,8 +20,8 @@ add_library(node-api-host SHARED ../cpp/Logger.cpp ../cpp/CxxNodeApiHostModule.cpp ../cpp/WeakNodeApiInjector.cpp - ../cpp/node_api_impl.cpp - ../cpp/node_api_impl.hpp + ../cpp/RuntimeNodeApi.cpp + ../cpp/RuntimeNodeApi.hpp ) target_include_directories(node-api-host PRIVATE diff --git a/packages/host/cpp/node_api_impl.cpp b/packages/host/cpp/RuntimeNodeApi.cpp similarity index 98% rename from packages/host/cpp/node_api_impl.cpp rename to packages/host/cpp/RuntimeNodeApi.cpp index 173f9b29..998a7297 100644 --- a/packages/host/cpp/node_api_impl.cpp +++ b/packages/host/cpp/RuntimeNodeApi.cpp @@ -1,4 +1,4 @@ -#include "node_api_impl.hpp" +#include "RuntimeNodeApi.hpp" #include auto ArrayType = napi_uint8_array; diff --git a/packages/host/cpp/node_api_impl.hpp b/packages/host/cpp/RuntimeNodeApi.hpp similarity index 100% rename from packages/host/cpp/node_api_impl.hpp rename to packages/host/cpp/RuntimeNodeApi.hpp diff --git a/packages/host/scripts/generate-weak-node-api-injector.ts b/packages/host/scripts/generate-weak-node-api-injector.ts index e1db9cfe..f7e14ce0 100644 --- a/packages/host/scripts/generate-weak-node-api-injector.ts +++ b/packages/host/scripts/generate-weak-node-api-injector.ts @@ -24,7 +24,7 @@ export function generateSource(functions: FunctionDecl[]) { #include #include #include - #include + #include #if defined(__APPLE__) #define WEAK_NODE_API_LIBRARY_NAME "@rpath/weak-node-api.framework/weak-node-api" From d6d57a18e2928119d8e3219db7476a83dc4c1da4 Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Fri, 11 Jul 2025 13:48:33 +0200 Subject: [PATCH 11/14] Removed gc related tests --- .../node-addon-examples/tests/buffers/addon.js | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/packages/node-addon-examples/tests/buffers/addon.js b/packages/node-addon-examples/tests/buffers/addon.js index 4f0f82a6..2e73501f 100644 --- a/packages/node-addon-examples/tests/buffers/addon.js +++ b/packages/node-addon-examples/tests/buffers/addon.js @@ -10,22 +10,10 @@ const toLocaleString = (text) => { .join(""); }; -console.log(toLocaleString(addon.newExternalBuffer()), addon.theText); console.log(addon.newBuffer().toLocaleString(), addon.theText); -console.log("gc1"); -console.log(addon.getDeleterCallCount(), 0); -global.gc(); -console.log(addon.getDeleterCallCount(), 1); -console.log(addon.getDeleterCallCount(), 1); +console.log(toLocaleString(addon.newExternalBuffer()), addon.theText); console.log(addon.copyBuffer(), addon.theText); - let buffer = addon.staticBuffer(); console.log(addon.bufferHasInstance(buffer), true); console.log(addon.bufferInfo(buffer), true); -buffer = null; -global.gc(); -console.log(addon.getDeleterCallCount(), 1); -console.log("gc2"); -console.log(addon.getDeleterCallCount(), 2); - addon.invalidObjectAsBuffer({}); From aa770f66ac77fd56698ea8138f98ee452fccc03a Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Fri, 11 Jul 2025 13:48:41 +0200 Subject: [PATCH 12/14] Cleaned up file --- packages/node-addon-examples/tests/buffers/package.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/node-addon-examples/tests/buffers/package.json b/packages/node-addon-examples/tests/buffers/package.json index 1690df57..d03151c7 100644 --- a/packages/node-addon-examples/tests/buffers/package.json +++ b/packages/node-addon-examples/tests/buffers/package.json @@ -10,7 +10,5 @@ "scripts": { "test": "node --expose-gc addon.js" }, - "gypfile": true, - "readme": "ERROR: No README data found!", - "_id": "function_arguments@0.0.0" + "gypfile": true } From 7c4e9aea87635870a1b4e8d499bf89515a65bc28 Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Fri, 11 Jul 2025 13:50:32 +0200 Subject: [PATCH 13/14] Renamed to IMPLEMENTED_RUNTIME_FUNCTIONS --- packages/host/scripts/generate-weak-node-api-injector.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/host/scripts/generate-weak-node-api-injector.ts b/packages/host/scripts/generate-weak-node-api-injector.ts index f7e14ce0..71e66893 100644 --- a/packages/host/scripts/generate-weak-node-api-injector.ts +++ b/packages/host/scripts/generate-weak-node-api-injector.ts @@ -7,7 +7,7 @@ import { FunctionDecl, getNodeApiFunctions } from "./node-api-functions"; export const CPP_SOURCE_PATH = path.join(__dirname, "../cpp"); // TODO: Remove when all runtime Node API functions are implemented -const implementedRuntimeFunctions = [ +const IMPLEMENTED_RUNTIME_FUNCTIONS = [ "napi_create_buffer", "napi_create_buffer_copy", "napi_is_buffer", @@ -55,7 +55,7 @@ export function generateSource(functions: FunctionDecl[]) { ${functions .filter( ({ kind, name }) => - kind === "engine" || implementedRuntimeFunctions.includes(name) + kind === "engine" || IMPLEMENTED_RUNTIME_FUNCTIONS.includes(name) ) .flatMap(({ name }) => `.${name} = ${name},`) .join("\n")} From 2441fc80661d842b55fc0968bbd1027bb8f0c0bc Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Fri, 11 Jul 2025 13:50:58 +0200 Subject: [PATCH 14/14] Added reference to the issue --- packages/host/cpp/RuntimeNodeApi.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/host/cpp/RuntimeNodeApi.cpp b/packages/host/cpp/RuntimeNodeApi.cpp index 998a7297..dc661833 100644 --- a/packages/host/cpp/RuntimeNodeApi.cpp +++ b/packages/host/cpp/RuntimeNodeApi.cpp @@ -11,6 +11,10 @@ napi_status NAPI_CDECL callstack::nodeapihost::napi_create_buffer( return status; } + // Warning: The returned data structure does not fully align with the + // characteristics of a Buffer. + // @see + // https://github.com/callstackincubator/react-native-node-api/issues/171 return napi_create_typedarray(env, ArrayType, length, buffer, 0, result); }