diff --git a/packages/runtime/src/env.ts b/packages/runtime/src/env.ts index ac7ac1ad..a04981f9 100644 --- a/packages/runtime/src/env.ts +++ b/packages/runtime/src/env.ts @@ -250,7 +250,7 @@ export class NodeEnv extends Env { } const hasProcess = typeof process === 'object' && process !== null const hasForceFlag = hasProcess ? Boolean(process.execArgv && (process.execArgv.indexOf('--force-node-api-uncaught-exceptions-policy') !== -1)) : false - if (!hasForceFlag && !enforceUncaughtExceptionPolicy) { + if (envObject.moduleApiVersion < NAPI_VERSION_EXPERIMENTAL && !hasForceFlag && !enforceUncaughtExceptionPolicy) { const warn = hasProcess && typeof process.emitWarning === 'function' ? process.emitWarning : function (warning: string | Error, type?: string, code?: string) { diff --git a/packages/test/CMakeLists.txt b/packages/test/CMakeLists.txt index caa7b0c1..fa5e766d 100644 --- a/packages/test/CMakeLists.txt +++ b/packages/test/CMakeLists.txt @@ -278,6 +278,7 @@ add_test("dataview" "./dataview/binding.c" OFF) add_test("date" "./date/binding.c" OFF) add_test("error" "./error/binding.c" OFF) add_test("exception" "./exception/binding.c" OFF) +add_test("ref_finalizer" "./ref_finalizer/binding.c" OFF) add_test("ref" "./ref/binding.c" OFF) add_test("ref_double_free" "./ref_double_free/binding.c" OFF) add_test("function" "./function/binding.c" OFF) @@ -287,6 +288,7 @@ add_test("number" "./number/binding.c;./number/test_null.c" OFF) add_test("symbol" "./symbol/binding.c" OFF) add_test("typedarray" "./typedarray/binding.c" OFF) add_test("buffer" "./buffer/binding.c" OFF) +add_test("buffer_finalizer" "./buffer_finalizer/binding.c" OFF) add_test("fatal_exception" "./fatal_exception/binding.c" OFF) add_test("cleanup_hook" "./cleanup_hook/binding.c" OFF) diff --git a/packages/test/buffer/binding.c b/packages/test/buffer/binding.c index d3e9c57e..0b5916f5 100644 --- a/packages/test/buffer/binding.c +++ b/packages/test/buffer/binding.c @@ -52,17 +52,6 @@ static void noopDeleter(napi_env env, void* data, void* finalize_hint) { deleterCallCount++; } -static void malignDeleter(napi_env env, void* data, void* finalize_hint) { - NODE_API_ASSERT_RETURN_VOID(env, data != NULL && strcmp(data, theText) == 0, "invalid data"); - napi_ref finalizer_ref = (napi_ref)finalize_hint; - napi_value js_finalizer; - napi_value recv; - NODE_API_CALL_RETURN_VOID(env, napi_get_reference_value(env, finalizer_ref, &js_finalizer)); - NODE_API_CALL_RETURN_VOID(env, napi_get_global(env, &recv)); - NODE_API_CALL_RETURN_VOID(env, napi_call_function(env, recv, js_finalizer, 0, NULL, NULL)); - NODE_API_CALL_RETURN_VOID(env, napi_delete_reference(env, finalizer_ref)); -} - static napi_value newBuffer(napi_env env, napi_callback_info info) { napi_value theBuffer; char* theCopy; @@ -150,30 +139,6 @@ static napi_value staticBuffer(napi_env env, napi_callback_info info) { return theBuffer; } -static napi_value malignFinalizerBuffer(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 finalizer = args[0]; - napi_valuetype finalizer_valuetype; - NODE_API_CALL(env, napi_typeof(env, finalizer, &finalizer_valuetype)); - NODE_API_ASSERT(env, finalizer_valuetype == napi_function, "Wrong type of first argument"); - napi_ref finalizer_ref; - NODE_API_CALL(env, napi_create_reference(env, finalizer, 1, &finalizer_ref)); - - napi_value theBuffer; - NODE_API_CALL( - env, - napi_create_external_buffer(env, - sizeof(theText), - (void*)theText, - malignDeleter, - finalizer_ref, // finalize_hint - &theBuffer)); - return theBuffer; -} - static napi_value getMemoryDataAsArray(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value args[1]; @@ -224,7 +189,6 @@ static napi_value Init(napi_env env, napi_value exports) { DECLARE_NODE_API_PROPERTY("bufferHasInstance", bufferHasInstance), DECLARE_NODE_API_PROPERTY("bufferInfo", bufferInfo), DECLARE_NODE_API_PROPERTY("staticBuffer", staticBuffer), - DECLARE_NODE_API_PROPERTY("malignFinalizerBuffer", malignFinalizerBuffer), DECLARE_NODE_API_PROPERTY("getMemoryDataAsArray", getMemoryDataAsArray), }; diff --git a/packages/test/buffer_finalizer/binding.c b/packages/test/buffer_finalizer/binding.c new file mode 100644 index 00000000..6d815de8 --- /dev/null +++ b/packages/test/buffer_finalizer/binding.c @@ -0,0 +1,69 @@ +#include +// #include +#include "../common.h" + +#if !defined(__wasm__) || (defined(__EMSCRIPTEN__) || defined(__wasi__)) +#include +#else +int strcmp(const char *l, const char *r) { + for (; *l==*r && *l; l++, r++); + return *(unsigned char *)l - *(unsigned char *)r; +} +#endif + +static const char theText[] = + "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; + +static void malignDeleter(napi_env env, void* data, void* finalize_hint) { + NODE_API_ASSERT_RETURN_VOID( + env, data != NULL && strcmp(data, theText) == 0, "invalid data"); + napi_ref finalizer_ref = (napi_ref)finalize_hint; + napi_value js_finalizer; + napi_value recv; + NODE_API_CALL_RETURN_VOID( + env, napi_get_reference_value(env, finalizer_ref, &js_finalizer)); + NODE_API_CALL_RETURN_VOID(env, napi_get_global(env, &recv)); + NODE_API_CALL_RETURN_VOID( + env, napi_call_function(env, recv, js_finalizer, 0, NULL, NULL)); + NODE_API_CALL_RETURN_VOID(env, napi_delete_reference(env, finalizer_ref)); +} + +static napi_value malignFinalizerBuffer(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 finalizer = args[0]; + napi_valuetype finalizer_valuetype; + NODE_API_CALL(env, napi_typeof(env, finalizer, &finalizer_valuetype)); + NODE_API_ASSERT(env, + finalizer_valuetype == napi_function, + "Wrong type of first argument"); + napi_ref finalizer_ref; + NODE_API_CALL(env, napi_create_reference(env, finalizer, 1, &finalizer_ref)); + + napi_value theBuffer; + NODE_API_CALL(env, + napi_create_external_buffer(env, + sizeof(theText), + (void*)theText, + malignDeleter, + finalizer_ref, // finalize_hint + &theBuffer)); + return theBuffer; +} + +static napi_value Init(napi_env env, napi_value exports) { + napi_property_descriptor methods[] = { + DECLARE_NODE_API_PROPERTY("malignFinalizerBuffer", malignFinalizerBuffer), + }; + + NODE_API_CALL( + env, + napi_define_properties( + env, exports, sizeof(methods) / sizeof(methods[0]), methods)); + + return exports; +} + +NAPI_MODULE(NODE_GYP_MODULE_NAME, Init) diff --git a/packages/test/buffer/buffer.finalizer.test.js b/packages/test/buffer_finalizer/buffer_finalizer.test.js similarity index 94% rename from packages/test/buffer/buffer.finalizer.test.js rename to packages/test/buffer_finalizer/buffer_finalizer.test.js index 0efb049b..4216d0ee 100644 --- a/packages/test/buffer/buffer.finalizer.test.js +++ b/packages/test/buffer_finalizer/buffer_finalizer.test.js @@ -10,7 +10,7 @@ process.on('uncaughtException', common.mustCall((err) => { })) async function main () { - const binding = await load('buffer') + const binding = await load('buffer_finalizer') await (async function () { // eslint-disable-next-line no-lone-blocks diff --git a/packages/test/ref/binding.c b/packages/test/ref/binding.c index 60567878..651d6bc3 100644 --- a/packages/test/ref/binding.c +++ b/packages/test/ref/binding.c @@ -25,20 +25,6 @@ static void FinalizeExternal(napi_env env, void* data, void* hint) { finalize_count++; } -static void FinalizeExternalCallJs(napi_env env, void* data, void* hint) { - int *actual_value = data; - NODE_API_ASSERT_RETURN_VOID(env, actual_value == &test_value, - "The correct pointer was passed to the finalizer"); - - napi_ref finalizer_ref = (napi_ref)hint; - napi_value js_finalizer; - napi_value recv; - NODE_API_CALL_RETURN_VOID(env, napi_get_reference_value(env, finalizer_ref, &js_finalizer)); - NODE_API_CALL_RETURN_VOID(env, napi_get_global(env, &recv)); - NODE_API_CALL_RETURN_VOID(env, napi_call_function(env, recv, js_finalizer, 0, NULL, NULL)); - NODE_API_CALL_RETURN_VOID(env, napi_delete_reference(env, finalizer_ref)); -} - static napi_value CreateExternal(napi_env env, napi_callback_info info) { int* data = &test_value; @@ -117,31 +103,6 @@ CreateExternalWithFinalize(napi_env env, napi_callback_info info) { return result; } -static napi_value -CreateExternalWithJsFinalize(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 finalizer = args[0]; - napi_valuetype finalizer_valuetype; - NODE_API_CALL(env, napi_typeof(env, finalizer, &finalizer_valuetype)); - NODE_API_ASSERT(env, finalizer_valuetype == napi_function, "Wrong type of first argument"); - napi_ref finalizer_ref; - NODE_API_CALL(env, napi_create_reference(env, finalizer, 1, &finalizer_ref)); - - napi_value result; - NODE_API_CALL(env, - napi_create_external(env, - &test_value, - FinalizeExternalCallJs, - finalizer_ref, /* finalize_hint */ - &result)); - - finalize_count = 0; - return result; -} - static napi_value CheckExternal(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value arg; @@ -262,24 +223,24 @@ static napi_value ValidateDeleteBeforeFinalize(napi_env env, napi_callback_info EXTERN_C_START napi_value Init(napi_env env, napi_value exports) { napi_property_descriptor descriptors[] = { - DECLARE_NODE_API_GETTER("finalizeCount", GetFinalizeCount), - DECLARE_NODE_API_PROPERTY("createExternal", CreateExternal), - DECLARE_NODE_API_PROPERTY("createExternalWithFinalize", - CreateExternalWithFinalize), - DECLARE_NODE_API_PROPERTY("createExternalWithJsFinalize", - CreateExternalWithJsFinalize), - DECLARE_NODE_API_PROPERTY("checkExternal", CheckExternal), - DECLARE_NODE_API_PROPERTY("createReference", CreateReference), - DECLARE_NODE_API_PROPERTY("createSymbol", CreateSymbol), - DECLARE_NODE_API_PROPERTY("createSymbolFor", CreateSymbolFor), - DECLARE_NODE_API_PROPERTY("createSymbolForEmptyString", CreateSymbolForEmptyString), - DECLARE_NODE_API_PROPERTY("createSymbolForIncorrectLength", CreateSymbolForIncorrectLength), - DECLARE_NODE_API_PROPERTY("deleteReference", DeleteReference), - DECLARE_NODE_API_PROPERTY("incrementRefcount", IncrementRefcount), - DECLARE_NODE_API_PROPERTY("decrementRefcount", DecrementRefcount), - DECLARE_NODE_API_GETTER("referenceValue", GetReferenceValue), - DECLARE_NODE_API_PROPERTY("validateDeleteBeforeFinalize", - ValidateDeleteBeforeFinalize), + DECLARE_NODE_API_GETTER("finalizeCount", GetFinalizeCount), + DECLARE_NODE_API_PROPERTY("createExternal", CreateExternal), + DECLARE_NODE_API_PROPERTY("createExternalWithFinalize", + CreateExternalWithFinalize), + DECLARE_NODE_API_PROPERTY("checkExternal", CheckExternal), + DECLARE_NODE_API_PROPERTY("createReference", CreateReference), + DECLARE_NODE_API_PROPERTY("createSymbol", CreateSymbol), + DECLARE_NODE_API_PROPERTY("createSymbolFor", CreateSymbolFor), + DECLARE_NODE_API_PROPERTY("createSymbolForEmptyString", + CreateSymbolForEmptyString), + DECLARE_NODE_API_PROPERTY("createSymbolForIncorrectLength", + CreateSymbolForIncorrectLength), + DECLARE_NODE_API_PROPERTY("deleteReference", DeleteReference), + DECLARE_NODE_API_PROPERTY("incrementRefcount", IncrementRefcount), + DECLARE_NODE_API_PROPERTY("decrementRefcount", DecrementRefcount), + DECLARE_NODE_API_GETTER("referenceValue", GetReferenceValue), + DECLARE_NODE_API_PROPERTY("validateDeleteBeforeFinalize", + ValidateDeleteBeforeFinalize), }; NODE_API_CALL(env, napi_define_properties( diff --git a/packages/test/ref_finalizer/binding.c b/packages/test/ref_finalizer/binding.c new file mode 100644 index 00000000..ab6aeffa --- /dev/null +++ b/packages/test/ref_finalizer/binding.c @@ -0,0 +1,71 @@ +// #include +#include +// #include +#include "../common.h" +#include "../entry_point.h" + +static int test_value = 1; +static int finalize_count = 0; + +static void FinalizeExternalCallJs(napi_env env, void* data, void* hint) { + int* actual_value = data; + NODE_API_ASSERT_RETURN_VOID( + env, + actual_value == &test_value, + "The correct pointer was passed to the finalizer"); + + napi_ref finalizer_ref = (napi_ref)hint; + napi_value js_finalizer; + napi_value recv; + NODE_API_CALL_RETURN_VOID( + env, napi_get_reference_value(env, finalizer_ref, &js_finalizer)); + NODE_API_CALL_RETURN_VOID(env, napi_get_global(env, &recv)); + NODE_API_CALL_RETURN_VOID( + env, napi_call_function(env, recv, js_finalizer, 0, NULL, NULL)); + NODE_API_CALL_RETURN_VOID(env, napi_delete_reference(env, finalizer_ref)); +} + +static napi_value CreateExternalWithJsFinalize(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 finalizer = args[0]; + napi_valuetype finalizer_valuetype; + NODE_API_CALL(env, napi_typeof(env, finalizer, &finalizer_valuetype)); + NODE_API_ASSERT(env, + finalizer_valuetype == napi_function, + "Wrong type of first argument"); + napi_ref finalizer_ref; + NODE_API_CALL(env, napi_create_reference(env, finalizer, 1, &finalizer_ref)); + + napi_value result; + NODE_API_CALL(env, + napi_create_external(env, + &test_value, + FinalizeExternalCallJs, + finalizer_ref, /* finalize_hint */ + &result)); + + finalize_count = 0; + return result; +} + +EXTERN_C_START +napi_value Init(napi_env env, napi_value exports) { + napi_property_descriptor descriptors[] = { + DECLARE_NODE_API_PROPERTY("createExternalWithJsFinalize", + CreateExternalWithJsFinalize), + }; + + NODE_API_CALL( + env, + napi_define_properties(env, + exports, + sizeof(descriptors) / sizeof(*descriptors), + descriptors)); + + return exports; +} +EXTERN_C_END diff --git a/packages/test/ref/ref_finalizer.test.js b/packages/test/ref_finalizer/ref_finalizer.test.js similarity index 90% rename from packages/test/ref/ref_finalizer.test.js rename to packages/test/ref_finalizer/ref_finalizer.test.js index 5fd08d22..200fa091 100644 --- a/packages/test/ref/ref_finalizer.test.js +++ b/packages/test/ref_finalizer/ref_finalizer.test.js @@ -21,9 +21,9 @@ module.exports = new Promise((resolve) => { }) const p2 = new Promise((resolve, reject) => { - load('ref').then((test_reference) => { + load('ref_finalizer').then((binding) => { { - test_reference.createExternalWithJsFinalize( + binding.createExternalWithJsFinalize( common.mustCall(() => { throw new Error('finalizer error') }))