Skip to content

Commit

Permalink
enable uncaught exceptions policy by default (#81)
Browse files Browse the repository at this point in the history
  • Loading branch information
toyobayashi authored Sep 26, 2023
1 parent f04d9ed commit 8b4551b
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 97 deletions.
2 changes: 1 addition & 1 deletion packages/runtime/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions packages/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)

Expand Down
36 changes: 0 additions & 36 deletions packages/test/buffer/binding.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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),
};

Expand Down
69 changes: 69 additions & 0 deletions packages/test/buffer_finalizer/binding.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include <node_api.h>
// #include <stdlib.h>
#include "../common.h"

#if !defined(__wasm__) || (defined(__EMSCRIPTEN__) || defined(__wasi__))
#include <string.h>
#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)
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
75 changes: 18 additions & 57 deletions packages/test/ref/binding.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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(
Expand Down
71 changes: 71 additions & 0 deletions packages/test/ref_finalizer/binding.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// #include <assert.h>
#include <js_native_api.h>
// #include <stdlib.h>
#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
Original file line number Diff line number Diff line change
Expand Up @@ -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')
}))
Expand Down

0 comments on commit 8b4551b

Please sign in to comment.