11cb0ef41Sopenharmony_ci#include <node_api.h> 21cb0ef41Sopenharmony_ci#include <assert.h> 31cb0ef41Sopenharmony_ci#include "../../js-native-api/common.h" 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#define MAX_ARGUMENTS 10 61cb0ef41Sopenharmony_ci#define RESERVED_ARGS 3 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_cistatic napi_value MakeCallback(napi_env env, napi_callback_info info) { 91cb0ef41Sopenharmony_ci size_t argc = MAX_ARGUMENTS; 101cb0ef41Sopenharmony_ci size_t n; 111cb0ef41Sopenharmony_ci napi_value args[MAX_ARGUMENTS]; 121cb0ef41Sopenharmony_ci // NOLINTNEXTLINE (readability/null_usage) 131cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL)); 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ci NODE_API_ASSERT(env, argc > 0, "Wrong number of arguments"); 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ci napi_value async_context_wrap = args[0]; 181cb0ef41Sopenharmony_ci napi_value recv = args[1]; 191cb0ef41Sopenharmony_ci napi_value func = args[2]; 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci napi_value argv[MAX_ARGUMENTS - RESERVED_ARGS]; 221cb0ef41Sopenharmony_ci for (n = RESERVED_ARGS; n < argc; n += 1) { 231cb0ef41Sopenharmony_ci argv[n - RESERVED_ARGS] = args[n]; 241cb0ef41Sopenharmony_ci } 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci napi_valuetype func_type; 271cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_typeof(env, func, &func_type)); 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ci napi_async_context context; 301cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_unwrap(env, async_context_wrap, (void**)&context)); 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci napi_value result; 331cb0ef41Sopenharmony_ci if (func_type == napi_function) { 341cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_make_callback( 351cb0ef41Sopenharmony_ci env, context, recv, func, argc - RESERVED_ARGS, argv, &result)); 361cb0ef41Sopenharmony_ci } else { 371cb0ef41Sopenharmony_ci NODE_API_ASSERT(env, false, "Unexpected argument type"); 381cb0ef41Sopenharmony_ci } 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci return result; 411cb0ef41Sopenharmony_ci} 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_cistatic void AsyncDestroyCb(napi_env env, void* data, void* hint) { 441cb0ef41Sopenharmony_ci napi_status status = napi_async_destroy(env, (napi_async_context)data); 451cb0ef41Sopenharmony_ci // We cannot use NODE_API_ASSERT_RETURN_VOID because we need to have a JS 461cb0ef41Sopenharmony_ci // stack below in order to use exceptions. 471cb0ef41Sopenharmony_ci assert(status == napi_ok); 481cb0ef41Sopenharmony_ci} 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ci#define CREATE_ASYNC_RESOURCE_ARGC 2 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_cistatic napi_value CreateAsyncResource(napi_env env, napi_callback_info info) { 531cb0ef41Sopenharmony_ci napi_value async_context_wrap; 541cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_create_object(env, &async_context_wrap)); 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci size_t argc = CREATE_ASYNC_RESOURCE_ARGC; 571cb0ef41Sopenharmony_ci napi_value args[CREATE_ASYNC_RESOURCE_ARGC]; 581cb0ef41Sopenharmony_ci // NOLINTNEXTLINE (readability/null_usage) 591cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL)); 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci napi_value resource = args[0]; 621cb0ef41Sopenharmony_ci napi_value js_destroy_on_finalizer = args[1]; 631cb0ef41Sopenharmony_ci napi_valuetype resource_type; 641cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_typeof(env, resource, &resource_type)); 651cb0ef41Sopenharmony_ci if (resource_type != napi_object) { 661cb0ef41Sopenharmony_ci resource = NULL; 671cb0ef41Sopenharmony_ci } 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci napi_value resource_name; 701cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_create_string_utf8( 711cb0ef41Sopenharmony_ci env, "test_async", NAPI_AUTO_LENGTH, &resource_name)); 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci napi_async_context context; 741cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_async_init(env, resource, resource_name, &context)); 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci bool destroy_on_finalizer = true; 771cb0ef41Sopenharmony_ci if (argc == 2) { 781cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_get_value_bool(env, js_destroy_on_finalizer, &destroy_on_finalizer)); 791cb0ef41Sopenharmony_ci } 801cb0ef41Sopenharmony_ci if (resource_type == napi_object && destroy_on_finalizer) { 811cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_add_finalizer( 821cb0ef41Sopenharmony_ci env, resource, (void*)context, AsyncDestroyCb, NULL, NULL)); 831cb0ef41Sopenharmony_ci } 841cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_wrap(env, async_context_wrap, context, NULL, NULL, NULL)); 851cb0ef41Sopenharmony_ci return async_context_wrap; 861cb0ef41Sopenharmony_ci} 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci#define DESTROY_ASYNC_RESOURCE_ARGC 1 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_cistatic napi_value DestroyAsyncResource(napi_env env, napi_callback_info info) { 911cb0ef41Sopenharmony_ci size_t argc = DESTROY_ASYNC_RESOURCE_ARGC; 921cb0ef41Sopenharmony_ci napi_value args[DESTROY_ASYNC_RESOURCE_ARGC]; 931cb0ef41Sopenharmony_ci // NOLINTNEXTLINE (readability/null_usage) 941cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL)); 951cb0ef41Sopenharmony_ci NODE_API_ASSERT(env, argc == 1, "Wrong number of arguments"); 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_ci napi_value async_context_wrap = args[0]; 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci napi_async_context async_context; 1001cb0ef41Sopenharmony_ci NODE_API_CALL(env, 1011cb0ef41Sopenharmony_ci napi_remove_wrap(env, async_context_wrap, (void**)&async_context)); 1021cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_async_destroy(env, async_context)); 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci return async_context_wrap; 1051cb0ef41Sopenharmony_ci} 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_cistatic 1081cb0ef41Sopenharmony_cinapi_value Init(napi_env env, napi_value exports) { 1091cb0ef41Sopenharmony_ci napi_value fn; 1101cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_create_function( 1111cb0ef41Sopenharmony_ci // NOLINTNEXTLINE (readability/null_usage) 1121cb0ef41Sopenharmony_ci env, NULL, NAPI_AUTO_LENGTH, MakeCallback, NULL, &fn)); 1131cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_set_named_property(env, exports, "makeCallback", fn)); 1141cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_create_function( 1151cb0ef41Sopenharmony_ci // NOLINTNEXTLINE (readability/null_usage) 1161cb0ef41Sopenharmony_ci env, NULL, NAPI_AUTO_LENGTH, CreateAsyncResource, NULL, &fn)); 1171cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_set_named_property( 1181cb0ef41Sopenharmony_ci env, exports, "createAsyncResource", fn)); 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_create_function( 1211cb0ef41Sopenharmony_ci // NOLINTNEXTLINE (readability/null_usage) 1221cb0ef41Sopenharmony_ci env, NULL, NAPI_AUTO_LENGTH, DestroyAsyncResource, NULL, &fn)); 1231cb0ef41Sopenharmony_ci NODE_API_CALL(env, napi_set_named_property( 1241cb0ef41Sopenharmony_ci env, exports, "destroyAsyncResource", fn)); 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ci return exports; 1271cb0ef41Sopenharmony_ci} 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ciNAPI_MODULE(NODE_GYP_MODULE_NAME, Init) 130