diff --git a/source/loaders/node_loader/bootstrap/lib/bootstrap.js b/source/loaders/node_loader/bootstrap/lib/bootstrap.js index 2ad993732a..5c19d3e16b 100644 --- a/source/loaders/node_loader/bootstrap/lib/bootstrap.js +++ b/source/loaders/node_loader/bootstrap/lib/bootstrap.js @@ -266,6 +266,7 @@ function node_loader_trampoline_discover_function(func) { if (node_loader_trampoline_is_callable(func)) { // Espree can't parse native code functions so we can do a workaround const str = func.toString().replace('{ [native code] }', '{}'); + const ast = espree.parse(`(${str})`, { ecmaVersion: 14 }); @@ -276,7 +277,7 @@ function node_loader_trampoline_discover_function(func) { if (node_loader_trampoline_is_valid_symbol(node)) { const args = node_loader_trampoline_discover_arguments(node); const discover = { - ptr: func, + func, signature: args, async: node.async, }; @@ -293,6 +294,91 @@ function node_loader_trampoline_discover_function(func) { } } +function node_loader_trampoline_discover_klass_attributes(node) { + let attributes = []; + for (let i = 0; i < node.length; i++) { + if (node[i].kind === 'constructor') + { + for (let exp of node[i].value.body.body) + { + if (exp.type === 'ExpressionStatement' && exp.expression.type === 'AssignmentExpression') { + let left = exp.expression.left; + + if (left.type == 'MemberExpression' && (left.object && left.object.type === 'ThisExpression')) { + attributes.push(left.property && left.property.name); + } + } + } + } + } + + return attributes; +} + +function node_loader_trampoline_discover_klass_methods(node, str) { + const ret = {}; + for (let method of node) { + if (method.type === 'MethodDefinition') { + let method_name = method.key.name; + if (method.kind === 'constructor') { + method_name = 'klass_' + method_name; + } + ret[method_name] = { + name: method.key.name, + signature: node_loader_trampoline_discover_arguments(method.value) + } + + if (method.kind === 'method' && str.substring(method.start-1, method.start+5) === 'static') { + ret[method_name].static = true; + } + } + } + + return ret +} + +function node_loader_trampoline_discover_klass(klass) { + try { + if (node_loader_trampoline_is_callable(klass)) { + const str = klass.toString(); + const ast = espree.parse(`(${str})`, { + ecmaVersion: 14 + }); + + const node = (ast.body[0].type === 'ExpressionStatement') && ast.body[0].expression; + if (node.type === 'ClassExpression') { + const methods = node_loader_trampoline_discover_klass_methods(node.body.body, str) + const discover = { + klass, + methods + }; + + if (node.id && node.id.name) { + discover['name'] = node.id.name; + } + + if (methods.klass_constructor) { + discover['attributes'] = node_loader_trampoline_discover_klass_attributes(node.body.body); + } + + return discover; + } + } + } catch (ex) { + console.log(`Exception while parsing '${klass}' in node_loader_trampoline_discover_klass`, ex); + } +} + +function node_loader_trampoline_discover_object(obj) { + if (typeof obj === 'object') { + const constructor = (obj && obj.constructor) && obj.constructor.name + if (constructor !== 'Object' && constructor !== 'Array') + return { + obj + }; + } +} + function node_loader_trampoline_discover(handle) { const discover = {}; @@ -305,8 +391,9 @@ function node_loader_trampoline_discover(handle) { for (let j = 0; j < keys.length; ++j) { const key = keys[j]; - const func = exports[key]; - const descriptor = node_loader_trampoline_discover_function(func); + const value = exports[key]; + const descriptor = node_loader_trampoline_discover_function(value) + || node_loader_trampoline_discover_klass(value) || node_loader_trampoline_discover_object(value); if (descriptor !== undefined) { discover[key] = descriptor; @@ -411,6 +498,8 @@ module.exports = ((impl, ptr) => { 'clear': node_loader_trampoline_clear, 'discover': node_loader_trampoline_discover, 'discover_function': node_loader_trampoline_discover_function, + 'discover_klass': node_loader_trampoline_discover_klass, + 'discover_object': node_loader_trampoline_discover_object, 'test': node_loader_trampoline_test, 'await_function': node_loader_trampoline_await_function(trampoline), 'await_future': node_loader_trampoline_await_future(trampoline), diff --git a/source/loaders/node_loader/source/node_loader_impl.cpp b/source/loaders/node_loader/source/node_loader_impl.cpp index 76f14ccee1..ab6c40d382 100644 --- a/source/loaders/node_loader/source/node_loader_impl.cpp +++ b/source/loaders/node_loader/source/node_loader_impl.cpp @@ -3406,249 +3406,259 @@ void node_loader_impl_discover_safe(napi_env env, loader_impl_async_discover_saf node_loader_impl_exception(env, status); - /* Get function pointer */ - status = napi_get_named_property(env, function_descriptor, "ptr", &function_ptr); + /* Check if function pointer exists */ + bool is_func = false; - node_loader_impl_exception(env, status); - - /* Check function pointer type */ - status = napi_typeof(env, function_ptr, &valuetype); + status = napi_has_named_property(env, function_descriptor, "func", &is_func); node_loader_impl_exception(env, status); - if (valuetype != napi_function) + if (is_func == true) { - napi_throw_type_error(env, nullptr, "Invalid NodeJS function"); - } + /* Get function pointer */ + status = napi_get_named_property(env, function_descriptor, "func", &function_ptr); - /* Get function signature */ - status = napi_get_named_property(env, function_descriptor, "signature", &function_sig); + node_loader_impl_exception(env, status); - node_loader_impl_exception(env, status); + /* Check function pointer type */ + status = napi_typeof(env, function_ptr, &valuetype); - /* Check function pointer type */ - status = napi_typeof(env, function_sig, &valuetype); + node_loader_impl_exception(env, status); - node_loader_impl_exception(env, status); + if (valuetype != napi_function) + { + napi_throw_type_error(env, nullptr, "Invalid NodeJS function"); + } - if (valuetype != napi_object) - { - napi_throw_type_error(env, nullptr, "Invalid NodeJS signature"); - } + /* Get function signature */ + status = napi_get_named_property(env, function_descriptor, "signature", &function_sig); - /* Get signature length */ - status = napi_get_array_length(env, function_sig, &function_sig_length); + node_loader_impl_exception(env, status); - node_loader_impl_exception(env, status); + /* Check function pointer type */ + status = napi_typeof(env, function_sig, &valuetype); - /* Get function async */ - status = napi_get_named_property(env, function_descriptor, "async", &function_is_async); + node_loader_impl_exception(env, status); - node_loader_impl_exception(env, status); + if (valuetype != napi_object) + { + napi_throw_type_error(env, nullptr, "Invalid NodeJS signature"); + } - /* Check function async type */ - status = napi_typeof(env, function_is_async, &valuetype); + /* Get signature length */ + status = napi_get_array_length(env, function_sig, &function_sig_length); - node_loader_impl_exception(env, status); + node_loader_impl_exception(env, status); - if (valuetype != napi_boolean) - { - napi_throw_type_error(env, nullptr, "Invalid NodeJS async flag"); - } + /* Get function async */ + status = napi_get_named_property(env, function_descriptor, "async", &function_is_async); - /* Optionally retrieve types if any in order to support typed supersets of JavaScript like TypeScript */ - static const char types_str[] = "types"; - bool has_types = false; + node_loader_impl_exception(env, status); - status = napi_has_named_property(env, function_descriptor, types_str, &has_types); + /* Check function async type */ + status = napi_typeof(env, function_is_async, &valuetype); - node_loader_impl_exception(env, status); + node_loader_impl_exception(env, status); - if (has_types == true) - { - status = napi_get_named_property(env, function_descriptor, types_str, &function_types); + if (valuetype != napi_boolean) + { + napi_throw_type_error(env, nullptr, "Invalid NodeJS async flag"); + } - node_loader_impl_exception(env, status); + /* Optionally retrieve types if any in order to support typed supersets of JavaScript like TypeScript */ + static const char types_str[] = "types"; + bool has_types = false; - /* Check types array type */ - status = napi_typeof(env, function_types, &valuetype); + status = napi_has_named_property(env, function_descriptor, types_str, &has_types); node_loader_impl_exception(env, status); - if (valuetype != napi_object) + if (has_types == true) { - napi_throw_type_error(env, nullptr, "Invalid NodeJS function types"); - } - } + status = napi_get_named_property(env, function_descriptor, types_str, &function_types); - /* Optionally retrieve return value type if any in order to support typed supersets of JavaScript like TypeScript */ - static const char ret_str[] = "ret"; - bool has_ret = false; + node_loader_impl_exception(env, status); - status = napi_has_named_property(env, function_descriptor, ret_str, &has_ret); + /* Check types array type */ + status = napi_typeof(env, function_types, &valuetype); - node_loader_impl_exception(env, status); + node_loader_impl_exception(env, status); - if (has_ret == true) - { - status = napi_get_named_property(env, function_descriptor, ret_str, &function_ret); + if (valuetype != napi_object) + { + napi_throw_type_error(env, nullptr, "Invalid NodeJS function types"); + } + } - node_loader_impl_exception(env, status); + /* Optionally retrieve return value type if any in order to support typed supersets of JavaScript like TypeScript */ + static const char ret_str[] = "ret"; + bool has_ret = false; - /* Check return value type */ - status = napi_typeof(env, function_ret, &valuetype); + status = napi_has_named_property(env, function_descriptor, ret_str, &has_ret); node_loader_impl_exception(env, status); - if (valuetype != napi_string) + if (has_ret == true) { - napi_throw_type_error(env, nullptr, "Invalid NodeJS return type"); - } - } + status = napi_get_named_property(env, function_descriptor, ret_str, &function_ret); - /* Create node function */ - loader_impl_node_function node_func = static_cast(malloc(sizeof(struct loader_impl_node_function_type))); + node_loader_impl_exception(env, status); - /* Create reference to function pointer */ - status = napi_create_reference(env, function_ptr, 1, &node_func->func_ref); + /* Check return value type */ + status = napi_typeof(env, function_ret, &valuetype); - node_loader_impl_exception(env, status); - - node_func->node_impl = discover_safe->node_impl; - node_func->impl = discover_safe->node_impl->impl; + node_loader_impl_exception(env, status); - /* Create function */ - function f = function_create(func_name_str, (size_t)function_sig_length, node_func, &function_node_singleton); + if (valuetype != napi_string) + { + napi_throw_type_error(env, nullptr, "Invalid NodeJS return type"); + } + } - if (f != NULL) - { - signature s = function_signature(f); - scope sp = context_scope(discover_safe->ctx); - bool is_async = false; + /* Create node function */ + loader_impl_node_function node_func = static_cast(malloc(sizeof(struct loader_impl_node_function_type))); - /* Set function async */ - status = napi_get_value_bool(env, function_is_async, &is_async); + /* Create reference to function pointer */ + status = napi_create_reference(env, function_ptr, 1, &node_func->func_ref); node_loader_impl_exception(env, status); - function_async(f, is_async == true ? ASYNCHRONOUS : SYNCHRONOUS); + node_func->node_impl = discover_safe->node_impl; + node_func->impl = discover_safe->node_impl->impl; + + /* Create function */ + function f = function_create(func_name_str, (size_t)function_sig_length, node_func, &function_node_singleton); - /* Set return value if any */ - if (has_ret) + if (f != NULL) { - size_t return_type_length; - char *return_type_str = NULL; + signature s = function_signature(f); + scope sp = context_scope(discover_safe->ctx); + bool is_async = false; - /* Get return value string length */ - status = napi_get_value_string_utf8(env, function_ret, NULL, 0, &return_type_length); + /* Set function async */ + status = napi_get_value_bool(env, function_is_async, &is_async); node_loader_impl_exception(env, status); - if (return_type_length > 0) - { - return_type_str = static_cast(malloc(sizeof(char) * (return_type_length + 1))); - } + function_async(f, is_async == true ? ASYNCHRONOUS : SYNCHRONOUS); - if (return_type_str != NULL) + /* Set return value if any */ + if (has_ret) { - /* Get parameter name string */ - status = napi_get_value_string_utf8(env, function_ret, return_type_str, return_type_length + 1, &return_type_length); - - node_loader_impl_exception(env, status); + size_t return_type_length; + char *return_type_str = NULL; - signature_set_return(s, loader_impl_type(discover_safe->node_impl->impl, return_type_str)); + /* Get return value string length */ + status = napi_get_value_string_utf8(env, function_ret, NULL, 0, &return_type_length); - free(return_type_str); - } - } - - /* Set signature */ - for (uint32_t arg_index = 0; arg_index < function_sig_length; ++arg_index) - { - napi_value parameter_name; - size_t parameter_name_length; - char *parameter_name_str = NULL; + node_loader_impl_exception(env, status); - /* Get signature parameter name */ - status = napi_get_element(env, function_sig, arg_index, ¶meter_name); + if (return_type_length > 0) + { + return_type_str = static_cast(malloc(sizeof(char) * (return_type_length + 1))); + } - node_loader_impl_exception(env, status); + if (return_type_str != NULL) + { + /* Get parameter name string */ + status = napi_get_value_string_utf8(env, function_ret, return_type_str, return_type_length + 1, &return_type_length); - /* Get parameter name string length */ - status = napi_get_value_string_utf8(env, parameter_name, NULL, 0, ¶meter_name_length); + node_loader_impl_exception(env, status); - node_loader_impl_exception(env, status); + signature_set_return(s, loader_impl_type(discover_safe->node_impl->impl, return_type_str)); - if (parameter_name_length > 0) - { - parameter_name_str = static_cast(malloc(sizeof(char) * (parameter_name_length + 1))); + free(return_type_str); + } } - /* Get parameter name string */ - status = napi_get_value_string_utf8(env, parameter_name, parameter_name_str, parameter_name_length + 1, ¶meter_name_length); - - node_loader_impl_exception(env, status); - - /* Check if type info is available */ - if (has_types) + /* Set signature */ + for (uint32_t arg_index = 0; arg_index < function_sig_length; ++arg_index) { - napi_value parameter_type; - size_t parameter_type_length; - char *parameter_type_str = NULL; + napi_value parameter_name; + size_t parameter_name_length; + char *parameter_name_str = NULL; - /* Get signature parameter type */ - status = napi_get_element(env, function_types, arg_index, ¶meter_type); + /* Get signature parameter name */ + status = napi_get_element(env, function_sig, arg_index, ¶meter_name); node_loader_impl_exception(env, status); - /* Get parameter type string length */ - status = napi_get_value_string_utf8(env, parameter_type, NULL, 0, ¶meter_type_length); + /* Get parameter name string length */ + status = napi_get_value_string_utf8(env, parameter_name, NULL, 0, ¶meter_name_length); node_loader_impl_exception(env, status); - if (parameter_type_length > 0) + if (parameter_name_length > 0) { - parameter_type_str = static_cast(malloc(sizeof(char) * (parameter_type_length + 1))); + parameter_name_str = static_cast(malloc(sizeof(char) * (parameter_name_length + 1))); } - /* Get parameter type string */ - status = napi_get_value_string_utf8(env, parameter_type, parameter_type_str, parameter_type_length + 1, ¶meter_type_length); + /* Get parameter name string */ + status = napi_get_value_string_utf8(env, parameter_name, parameter_name_str, parameter_name_length + 1, ¶meter_name_length); node_loader_impl_exception(env, status); - signature_set(s, (size_t)arg_index, parameter_name_str, loader_impl_type(discover_safe->node_impl->impl, parameter_type_str)); + /* Check if type info is available */ + if (has_types) + { + napi_value parameter_type; + size_t parameter_type_length; + char *parameter_type_str = NULL; + + /* Get signature parameter type */ + status = napi_get_element(env, function_types, arg_index, ¶meter_type); + + node_loader_impl_exception(env, status); + + /* Get parameter type string length */ + status = napi_get_value_string_utf8(env, parameter_type, NULL, 0, ¶meter_type_length); + + node_loader_impl_exception(env, status); + + if (parameter_type_length > 0) + { + parameter_type_str = static_cast(malloc(sizeof(char) * (parameter_type_length + 1))); + } + + /* Get parameter type string */ + status = napi_get_value_string_utf8(env, parameter_type, parameter_type_str, parameter_type_length + 1, ¶meter_type_length); + + node_loader_impl_exception(env, status); - if (parameter_type_str != NULL) + signature_set(s, (size_t)arg_index, parameter_name_str, loader_impl_type(discover_safe->node_impl->impl, parameter_type_str)); + + if (parameter_type_str != NULL) + { + free(parameter_type_str); + } + } + else { - free(parameter_type_str); + signature_set(s, (size_t)arg_index, parameter_name_str, NULL); + } + + if (parameter_name_str != NULL) + { + free(parameter_name_str); } } - else - { - signature_set(s, (size_t)arg_index, parameter_name_str, NULL); - } - if (parameter_name_str != NULL) + value v = value_create_function(f); + + if (scope_define(sp, function_name(f), v) != 0) { - free(parameter_name_str); + value_type_destroy(v); + discover_safe->result = 1; + break; } } - - value v = value_create_function(f); - - if (scope_define(sp, function_name(f), v) != 0) + else { - value_type_destroy(v); + free(node_func); discover_safe->result = 1; break; } } - else - { - free(node_func); - discover_safe->result = 1; - break; - } free(func_name_str); } @@ -3807,210 +3817,210 @@ void *node_loader_impl_register(void *node_impl_ptr, void *env_ptr, void *functi { static const char threadsafe_func_name_str[] = "node_loader_impl_async_initialize_safe"; - node_loader_impl_thread_safe_function_initialize( - env, - threadsafe_func_name_str, sizeof(threadsafe_func_name_str), - &node_loader_impl_async_initialize_safe, - (loader_impl_async_initialize_safe_type **)(&node_impl->initialize_safe), - &node_impl->initialize_safe_ptr, - &node_impl->threadsafe_initialize); - } + node_loader_impl_thread_safe_function_initialize( + env, + threadsafe_func_name_str, sizeof(threadsafe_func_name_str), + &node_loader_impl_async_initialize_safe, + (loader_impl_async_initialize_safe_type **)(&node_impl->initialize_safe), + &node_impl->initialize_safe_ptr, + &node_impl->threadsafe_initialize); +} - /* Safe execution path */ - { - static const char threadsafe_func_name_str[] = "node_loader_impl_async_execution_path_safe"; - - node_loader_impl_thread_safe_function_initialize( - env, - threadsafe_func_name_str, sizeof(threadsafe_func_name_str), - &node_loader_impl_async_execution_path_safe, - (loader_impl_async_execution_path_safe_type **)(&node_impl->execution_path_safe), - &node_impl->execution_path_safe_ptr, - &node_impl->threadsafe_execution_path); - } +/* Safe execution path */ +{ + static const char threadsafe_func_name_str[] = "node_loader_impl_async_execution_path_safe"; + + node_loader_impl_thread_safe_function_initialize( + env, + threadsafe_func_name_str, sizeof(threadsafe_func_name_str), + &node_loader_impl_async_execution_path_safe, + (loader_impl_async_execution_path_safe_type **)(&node_impl->execution_path_safe), + &node_impl->execution_path_safe_ptr, + &node_impl->threadsafe_execution_path); +} - /* Safe load from file */ - { - static const char threadsafe_func_name_str[] = "node_loader_impl_async_load_from_file_safe"; - - node_loader_impl_thread_safe_function_initialize( - env, - threadsafe_func_name_str, sizeof(threadsafe_func_name_str), - &node_loader_impl_async_load_from_file_safe, - (loader_impl_async_load_from_file_safe_type **)(&node_impl->load_from_file_safe), - &node_impl->load_from_file_safe_ptr, - &node_impl->threadsafe_load_from_file); - } +/* Safe load from file */ +{ + static const char threadsafe_func_name_str[] = "node_loader_impl_async_load_from_file_safe"; + + node_loader_impl_thread_safe_function_initialize( + env, + threadsafe_func_name_str, sizeof(threadsafe_func_name_str), + &node_loader_impl_async_load_from_file_safe, + (loader_impl_async_load_from_file_safe_type **)(&node_impl->load_from_file_safe), + &node_impl->load_from_file_safe_ptr, + &node_impl->threadsafe_load_from_file); +} - /* Safe load from memory */ - { - static const char threadsafe_func_name_str[] = "node_loader_impl_async_load_from_memory_safe"; - - node_loader_impl_thread_safe_function_initialize( - env, - threadsafe_func_name_str, sizeof(threadsafe_func_name_str), - &node_loader_impl_async_load_from_memory_safe, - (loader_impl_async_load_from_memory_safe_type **)(&node_impl->load_from_memory_safe), - &node_impl->load_from_memory_safe_ptr, - &node_impl->threadsafe_load_from_memory); - } +/* Safe load from memory */ +{ + static const char threadsafe_func_name_str[] = "node_loader_impl_async_load_from_memory_safe"; + + node_loader_impl_thread_safe_function_initialize( + env, + threadsafe_func_name_str, sizeof(threadsafe_func_name_str), + &node_loader_impl_async_load_from_memory_safe, + (loader_impl_async_load_from_memory_safe_type **)(&node_impl->load_from_memory_safe), + &node_impl->load_from_memory_safe_ptr, + &node_impl->threadsafe_load_from_memory); +} - /* Safe clear */ - { - static const char threadsafe_func_name_str[] = "node_loader_impl_async_clear_safe"; - - node_loader_impl_thread_safe_function_initialize( - env, - threadsafe_func_name_str, sizeof(threadsafe_func_name_str), - &node_loader_impl_async_clear_safe, - (loader_impl_async_clear_safe_type **)(&node_impl->clear_safe), - &node_impl->clear_safe_ptr, - &node_impl->threadsafe_clear); - } +/* Safe clear */ +{ + static const char threadsafe_func_name_str[] = "node_loader_impl_async_clear_safe"; + + node_loader_impl_thread_safe_function_initialize( + env, + threadsafe_func_name_str, sizeof(threadsafe_func_name_str), + &node_loader_impl_async_clear_safe, + (loader_impl_async_clear_safe_type **)(&node_impl->clear_safe), + &node_impl->clear_safe_ptr, + &node_impl->threadsafe_clear); +} - /* Safe discover */ - { - static const char threadsafe_func_name_str[] = "node_loader_impl_async_discover_safe"; - - node_loader_impl_thread_safe_function_initialize( - env, - threadsafe_func_name_str, sizeof(threadsafe_func_name_str), - &node_loader_impl_async_discover_safe, - (loader_impl_async_discover_safe_type **)(&node_impl->discover_safe), - &node_impl->discover_safe_ptr, - &node_impl->threadsafe_discover); - } +/* Safe discover */ +{ + static const char threadsafe_func_name_str[] = "node_loader_impl_async_discover_safe"; + + node_loader_impl_thread_safe_function_initialize( + env, + threadsafe_func_name_str, sizeof(threadsafe_func_name_str), + &node_loader_impl_async_discover_safe, + (loader_impl_async_discover_safe_type **)(&node_impl->discover_safe), + &node_impl->discover_safe_ptr, + &node_impl->threadsafe_discover); +} - /* Safe function call */ - { - static const char threadsafe_func_name_str[] = "node_loader_impl_async_func_call_safe"; - - node_loader_impl_thread_safe_function_initialize( - env, - threadsafe_func_name_str, sizeof(threadsafe_func_name_str), - &node_loader_impl_async_func_call_safe, - (loader_impl_async_func_call_safe_type **)(&node_impl->func_call_safe), - &node_impl->func_call_safe_ptr, - &node_impl->threadsafe_func_call); - } +/* Safe function call */ +{ + static const char threadsafe_func_name_str[] = "node_loader_impl_async_func_call_safe"; + + node_loader_impl_thread_safe_function_initialize( + env, + threadsafe_func_name_str, sizeof(threadsafe_func_name_str), + &node_loader_impl_async_func_call_safe, + (loader_impl_async_func_call_safe_type **)(&node_impl->func_call_safe), + &node_impl->func_call_safe_ptr, + &node_impl->threadsafe_func_call); +} - /* Safe function await */ - { - static const char threadsafe_func_name_str[] = "node_loader_impl_async_func_await_safe"; - - node_loader_impl_thread_safe_function_initialize( - env, - threadsafe_func_name_str, sizeof(threadsafe_func_name_str), - &node_loader_impl_async_func_await_safe, - (loader_impl_async_func_await_safe_type **)(&node_impl->func_await_safe), - &node_impl->func_await_safe_ptr, - &node_impl->threadsafe_func_await); - } +/* Safe function await */ +{ + static const char threadsafe_func_name_str[] = "node_loader_impl_async_func_await_safe"; + + node_loader_impl_thread_safe_function_initialize( + env, + threadsafe_func_name_str, sizeof(threadsafe_func_name_str), + &node_loader_impl_async_func_await_safe, + (loader_impl_async_func_await_safe_type **)(&node_impl->func_await_safe), + &node_impl->func_await_safe_ptr, + &node_impl->threadsafe_func_await); +} - /* Safe function destroy */ - { - static const char threadsafe_func_name_str[] = "node_loader_impl_async_func_destroy_safe"; - - node_loader_impl_thread_safe_function_initialize( - env, - threadsafe_func_name_str, sizeof(threadsafe_func_name_str), - &node_loader_impl_async_func_destroy_safe, - (loader_impl_async_func_destroy_safe_type **)(&node_impl->func_destroy_safe), - &node_impl->func_destroy_safe_ptr, - &node_impl->threadsafe_func_destroy); - } +/* Safe function destroy */ +{ + static const char threadsafe_func_name_str[] = "node_loader_impl_async_func_destroy_safe"; + + node_loader_impl_thread_safe_function_initialize( + env, + threadsafe_func_name_str, sizeof(threadsafe_func_name_str), + &node_loader_impl_async_func_destroy_safe, + (loader_impl_async_func_destroy_safe_type **)(&node_impl->func_destroy_safe), + &node_impl->func_destroy_safe_ptr, + &node_impl->threadsafe_func_destroy); +} - /* Safe future await */ - { - static const char threadsafe_func_name_str[] = "node_loader_impl_async_future_await_safe"; - - node_loader_impl_thread_safe_function_initialize( - env, - threadsafe_func_name_str, sizeof(threadsafe_func_name_str), - &node_loader_impl_async_future_await_safe, - (loader_impl_async_future_await_safe_type **)(&node_impl->future_await_safe), - &node_impl->future_await_safe_ptr, - &node_impl->threadsafe_future_await); - } +/* Safe future await */ +{ + static const char threadsafe_func_name_str[] = "node_loader_impl_async_future_await_safe"; + + node_loader_impl_thread_safe_function_initialize( + env, + threadsafe_func_name_str, sizeof(threadsafe_func_name_str), + &node_loader_impl_async_future_await_safe, + (loader_impl_async_future_await_safe_type **)(&node_impl->future_await_safe), + &node_impl->future_await_safe_ptr, + &node_impl->threadsafe_future_await); +} - /* Safe future delete */ - { - static const char threadsafe_func_name_str[] = "node_loader_impl_async_future_delete_safe"; - - node_loader_impl_thread_safe_function_initialize( - env, - threadsafe_func_name_str, sizeof(threadsafe_func_name_str), - &node_loader_impl_async_future_delete_safe, - (loader_impl_async_future_delete_safe_type **)(&node_impl->future_delete_safe), - &node_impl->future_delete_safe_ptr, - &node_impl->threadsafe_future_delete); - } +/* Safe future delete */ +{ + static const char threadsafe_func_name_str[] = "node_loader_impl_async_future_delete_safe"; + + node_loader_impl_thread_safe_function_initialize( + env, + threadsafe_func_name_str, sizeof(threadsafe_func_name_str), + &node_loader_impl_async_future_delete_safe, + (loader_impl_async_future_delete_safe_type **)(&node_impl->future_delete_safe), + &node_impl->future_delete_safe_ptr, + &node_impl->threadsafe_future_delete); +} - /* Safe destroy */ - { - static const char threadsafe_func_name_str[] = "node_loader_impl_async_destroy_safe"; - - node_loader_impl_thread_safe_function_initialize( - env, - threadsafe_func_name_str, sizeof(threadsafe_func_name_str), - &node_loader_impl_async_destroy_safe, - (loader_impl_async_destroy_safe_type **)(&node_impl->destroy_safe), - &node_impl->destroy_safe_ptr, - &node_impl->threadsafe_destroy); - } - } +/* Safe destroy */ +{ + static const char threadsafe_func_name_str[] = "node_loader_impl_async_destroy_safe"; + + node_loader_impl_thread_safe_function_initialize( + env, + threadsafe_func_name_str, sizeof(threadsafe_func_name_str), + &node_loader_impl_async_destroy_safe, + (loader_impl_async_destroy_safe_type **)(&node_impl->destroy_safe), + &node_impl->destroy_safe_ptr, + &node_impl->threadsafe_destroy); +} +} /* Run test function, this one can be called without thread safe mechanism */ /* because it is run already in the correct V8 thread */ #if (!defined(NDEBUG) || defined(DEBUG) || defined(_DEBUG) || defined(__DEBUG) || defined(__DEBUG__)) - { - static const char test_str[] = "test"; - napi_value test_str_value; +{ + static const char test_str[] = "test"; + napi_value test_str_value; - bool result = false; + bool result = false; - /* Retrieve test function from object table */ - status = napi_create_string_utf8(env, test_str, sizeof(test_str) - 1, &test_str_value); + /* Retrieve test function from object table */ + status = napi_create_string_utf8(env, test_str, sizeof(test_str) - 1, &test_str_value); - node_loader_impl_exception(env, status); + node_loader_impl_exception(env, status); - status = napi_has_own_property(env, function_table_object, test_str_value, &result); + status = napi_has_own_property(env, function_table_object, test_str_value, &result); - node_loader_impl_exception(env, status); + node_loader_impl_exception(env, status); - if (result == true) - { - napi_value function_trampoline_test; - napi_valuetype valuetype; + if (result == true) + { + napi_value function_trampoline_test; + napi_valuetype valuetype; - status = napi_get_named_property(env, function_table_object, test_str, &function_trampoline_test); + status = napi_get_named_property(env, function_table_object, test_str, &function_trampoline_test); - node_loader_impl_exception(env, status); + node_loader_impl_exception(env, status); - status = napi_typeof(env, function_trampoline_test, &valuetype); + status = napi_typeof(env, function_trampoline_test, &valuetype); - node_loader_impl_exception(env, status); + node_loader_impl_exception(env, status); - if (valuetype != napi_function) - { - napi_throw_type_error(env, nullptr, "Invalid function test in function table object"); - } + if (valuetype != napi_function) + { + napi_throw_type_error(env, nullptr, "Invalid function test in function table object"); + } - /* Call to test function */ - napi_value return_value; + /* Call to test function */ + napi_value return_value; - status = napi_call_function(env, global, function_trampoline_test, 0, nullptr, &return_value); + status = napi_call_function(env, global, function_trampoline_test, 0, nullptr, &return_value); - node_loader_impl_exception(env, status); - } + node_loader_impl_exception(env, status); } +} #endif - /* Store the amount of async handles that we have for the node loader, - * so we can count the user defined async handles */ - node_impl->base_active_handles = node_loader_impl_async_handles_count(node_impl); - node_impl->extra_active_handles.store(0); - node_impl->event_loop_empty.store(false); +/* Store the amount of async handles that we have for the node loader, + * so we can count the user defined async handles */ +node_impl->base_active_handles = node_loader_impl_async_handles_count(node_impl); +node_impl->extra_active_handles.store(0); +node_impl->event_loop_empty.store(false); /* On Windows, hook node extension loading mechanism in order to patch extensions linked to node.exe */ #if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1200) @@ -4021,10 +4031,10 @@ void *node_loader_impl_register(void *node_impl_ptr, void *env_ptr, void *functi /* Signal start condition */ uv_cond_signal(&node_impl->cond); - uv_mutex_unlock(&node_impl->mutex); +uv_mutex_unlock(&node_impl->mutex); - /* TODO: Return */ - return NULL; +/* TODO: Return */ +return NULL; } void node_loader_impl_thread(void *data) @@ -5251,10 +5261,10 @@ void node_loader_impl_destroy_safe_impl(loader_impl_node node_impl, napi_env env } /* NodeJS Loader needs to register that it is destroyed, because after this step - * some destructors can be still triggered, before the node_loader->destroy() has - * finished, so this destructors will try to execute the NodeJS unrefs while having - * the runtime (at least the NodeJS Loader related part) destroyed. - */ + * some destructors can be still triggered, before the node_loader->destroy() has + * finished, so this destructors will try to execute the NodeJS unrefs while having + * the runtime (at least the NodeJS Loader related part) destroyed. + */ loader_set_destroyed(node_impl->impl); }