mirror of https://github.com/nodejs/node.git
update API
This commit is contained in:
parent
ceaeb11d00
commit
42e76c85b3
|
@ -245,7 +245,7 @@ added: REPLACEME
|
|||
This is an opaque pointer that represents a Node.js platform configuration
|
||||
instance.
|
||||
|
||||
##### `node_embedding_exit_code`
|
||||
##### `node_embedding_status`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
|
@ -253,53 +253,25 @@ added: REPLACEME
|
|||
|
||||
> Stability: 1 - Experimental
|
||||
|
||||
The exit code returned from the C Node.js embedding APIs.
|
||||
The status code returned from the C Node.js embedding APIs.
|
||||
|
||||
```c
|
||||
typedef enum {
|
||||
node_embedding_exit_code_ok = 0,
|
||||
node_embedding_exit_code_generic_user_error = 1,
|
||||
node_embedding_exit_code_internal_js_parse_error = 3,
|
||||
node_embedding_exit_code_internal_js_evaluation_failure = 4,
|
||||
node_embedding_exit_code_v8_fatal_error = 5,
|
||||
node_embedding_exit_code_invalid_fatal_exception_monkey_patching = 6,
|
||||
node_embedding_exit_code_exception_in_fatal_exception_handler = 7,
|
||||
node_embedding_exit_code_invalid_command_line_argument = 9,
|
||||
node_embedding_exit_code_bootstrap_failure = 10,
|
||||
node_embedding_exit_code_invalid_command_line_argument2 = 12,
|
||||
node_embedding_exit_code_unsettled_top_level_await = 13,
|
||||
node_embedding_exit_code_startup_snapshot_failure = 14,
|
||||
node_embedding_exit_code_abort = 134,
|
||||
} node_embedding_exit_code;
|
||||
node_embedding_status_ok = 0,
|
||||
node_embedding_status_generic_error = 1,
|
||||
node_embedding_status_null_arg = 2,
|
||||
node_embedding_status_bad_arg = 3,
|
||||
node_embedding_status_error_exit_code = 512,
|
||||
} node_embedding_status;
|
||||
```
|
||||
|
||||
These values match to the C++ `node::ExitCode` enum that are used as Node.js
|
||||
process exit codes.
|
||||
|
||||
- `node_embedding_exit_code_ok` - No issues.
|
||||
- `node_embedding_exit_code_generic_user_error` - It was originally intended for
|
||||
uncaught JS exceptions from the user land but we actually use this for all
|
||||
kinds of generic errors.
|
||||
- `node_embedding_exit_code_internal_js_parse_error` - It is unused because we
|
||||
pre-compile all builtins during snapshot building, when we exit with 1 if
|
||||
there's any error.
|
||||
- `node_embedding_exit_code_internal_js_evaluation_failure` - It is actually
|
||||
unused. We exit with 1 in this case.
|
||||
- `node_embedding_exit_code_v8_fatal_error` - It is actually unused. We exit
|
||||
with 133 (128+`SIGTRAP`) or 134 (128+`SIGABRT`) in this case.
|
||||
- `node_embedding_exit_code_invalid_fatal_exception_monkey_patching`
|
||||
- `node_embedding_exit_code_exception_in_fatal_exception_handler`
|
||||
- `node_embedding_exit_code_invalid_command_line_argument`
|
||||
- `node_embedding_exit_code_bootstrap_failure`
|
||||
- `node_embedding_exit_code_invalid_command_line_argument2` - This was intended
|
||||
for invalid inspector arguments but is actually now just a duplicate of
|
||||
`node_embedding_exit_code_invalid_command_line_argument`.
|
||||
- `node_embedding_exit_code_unsettled_top_level_await` -
|
||||
- `node_embedding_exit_code_startup_snapshot_failure` -
|
||||
- `node_embedding_exit_code_abort` - If the process exits from unhandled signals
|
||||
e.g. `SIGABRT`, `SIGTRAP`, typically the exit codes are 128 + signal number.
|
||||
We also exit with certain error codes directly for legacy reasons. Here we
|
||||
define those that are used to normalize the exit code on Windows.
|
||||
- `node_embedding_status_ok` - No issues.
|
||||
- `node_embedding_status_generic_error` - Generic error code.
|
||||
- `node_embedding_status_null_arg` - One of non-optional arguments passed as
|
||||
NULL value.
|
||||
- `node_embedding_status_bad_arg` - One of the arguments has wrong value.
|
||||
- `node_embedding_status_error_exit_code` - A bit flag added to the Node.js exit
|
||||
code value if the error status is associated with an error code.
|
||||
|
||||
##### `node_embedding_platform_flags`
|
||||
|
||||
|
@ -313,53 +285,55 @@ Flags are used to initialize a Node.js platform instance.
|
|||
|
||||
```c
|
||||
typedef enum {
|
||||
node_embedding_platform_no_flags = 0,
|
||||
node_embedding_platform_enable_stdio_inheritance = 1 << 0,
|
||||
node_embedding_platform_disable_node_options_env = 1 << 1,
|
||||
node_embedding_platform_disable_cli_options = 1 << 2,
|
||||
node_embedding_platform_no_icu = 1 << 3,
|
||||
node_embedding_platform_no_stdio_initialization = 1 << 4,
|
||||
node_embedding_platform_no_default_signal_handling = 1 << 5,
|
||||
node_embedding_platform_no_init_openssl = 1 << 8,
|
||||
node_embedding_platform_no_parse_global_debug_variables = 1 << 9,
|
||||
node_embedding_platform_no_adjust_resource_limits = 1 << 10,
|
||||
node_embedding_platform_no_use_large_pages = 1 << 11,
|
||||
node_embedding_platform_no_print_help_or_version_output = 1 << 12,
|
||||
node_embedding_platform_generate_predictable_snapshot = 1 << 14,
|
||||
node_embedding_platform_flags_none = 0,
|
||||
node_embedding_platform_flags_enable_stdio_inheritance = 1 << 0,
|
||||
node_embedding_platform_flags_disable_node_options_env = 1 << 1,
|
||||
node_embedding_platform_flags_disable_cli_options = 1 << 2,
|
||||
node_embedding_platform_flags_no_icu = 1 << 3,
|
||||
node_embedding_platform_flags_no_stdio_initialization = 1 << 4,
|
||||
node_embedding_platform_flags_no_default_signal_handling = 1 << 5,
|
||||
node_embedding_platform_flags_no_init_openssl = 1 << 8,
|
||||
node_embedding_platform_flags_no_parse_global_debug_variables = 1 << 9,
|
||||
node_embedding_platform_flags_no_adjust_resource_limits = 1 << 10,
|
||||
node_embedding_platform_flags_no_use_large_pages = 1 << 11,
|
||||
node_embedding_platform_flags_no_print_help_or_version_output = 1 << 12,
|
||||
node_embedding_platform_flags_generate_predictable_snapshot = 1 << 14,
|
||||
} node_embedding_platform_flags;
|
||||
```
|
||||
|
||||
These flags match to the C++ `node::ProcessInitializationFlags` and control the
|
||||
Node.js platform initialization.
|
||||
|
||||
- `node_embedding_platform_no_flags` - The default flags.
|
||||
- `node_embedding_platform_enable_stdio_inheritance` - Enable `stdio`
|
||||
- `node_embedding_platform_flags_none` - The default flags.
|
||||
- `node_embedding_platform_flags_enable_stdio_inheritance` - Enable `stdio`
|
||||
inheritance, which is disabled by default. This flag is also implied by the
|
||||
`node_embedding_platform_no_stdio_initialization`.
|
||||
- `node_embedding_platform_disable_node_options_env` - Disable reading the
|
||||
`node_embedding_platform_flags_no_stdio_initialization`.
|
||||
- `node_embedding_platform_flags_disable_node_options_env` - Disable reading the
|
||||
`NODE_OPTIONS` environment variable.
|
||||
- `node_embedding_platform_disable_cli_options` - Do not parse CLI options.
|
||||
- `node_embedding_platform_no_icu` - Do not initialize ICU.
|
||||
- `node_embedding_platform_no_stdio_initialization` - Do not modify `stdio` file
|
||||
descriptor or TTY state.
|
||||
- `node_embedding_platform_no_default_signal_handling` - Do not register
|
||||
- `node_embedding_platform_flags_disable_cli_options` - Do not parse CLI
|
||||
options.
|
||||
- `node_embedding_platform_flags_no_icu` - Do not initialize ICU.
|
||||
- `node_embedding_platform_flags_no_stdio_initialization` - Do not modify
|
||||
`stdio` file descriptor or TTY state.
|
||||
- `node_embedding_platform_flags_no_default_signal_handling` - Do not register
|
||||
Node.js-specific signal handlers and reset other signal handlers to
|
||||
default state.
|
||||
- `node_embedding_platform_no_init_openssl` - Do not initialize OpenSSL config.
|
||||
- `node_embedding_platform_no_parse_global_debug_variables` - Do not initialize
|
||||
Node.js debugging based on environment variables.
|
||||
- `node_embedding_platform_no_adjust_resource_limits` - Do not adjust OS
|
||||
- `node_embedding_platform_flags_no_init_openssl` - Do not initialize OpenSSL
|
||||
config.
|
||||
- `node_embedding_platform_flags_no_parse_global_debug_variables` - Do not
|
||||
initialize Node.js debugging based on environment variables.
|
||||
- `node_embedding_platform_flags_no_adjust_resource_limits` - Do not adjust OS
|
||||
resource limits for this process.
|
||||
- `node_embedding_platform_no_use_large_pages` - Do not map code segments into
|
||||
large pages for this process.
|
||||
- `node_embedding_platform_no_print_help_or_version_output` - Skip printing
|
||||
output for `--help`, `--version`, `--v8-options`.
|
||||
- `node_embedding_platform_generate_predictable_snapshot` - Initialize the
|
||||
- `node_embedding_platform_flags_no_use_large_pages` - Do not map code segments
|
||||
into large pages for this process.
|
||||
- `node_embedding_platform_flags_no_print_help_or_version_output` - Skip
|
||||
printing output for `--help`, `--version`, `--v8-options`.
|
||||
- `node_embedding_platform_flags_generate_predictable_snapshot` - Initialize the
|
||||
process for predictable snapshot generation.
|
||||
|
||||
#### Callback types
|
||||
|
||||
##### `node_embedding_error_handler`
|
||||
##### `node_embedding_handle_error_callback`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
|
@ -368,11 +342,11 @@ added: REPLACEME
|
|||
> Stability: 1 - Experimental
|
||||
|
||||
```c
|
||||
typedef node_embedding_exit_code(NAPI_CDECL* node_embedding_error_handler)(
|
||||
typedef node_embedding_status(NAPI_CDECL* node_embedding_handle_error_callback)(
|
||||
void* handler_data,
|
||||
const char* messages[],
|
||||
size_t messages_size,
|
||||
node_embedding_exit_code exit_code);
|
||||
node_embedding_status exit_code);
|
||||
```
|
||||
|
||||
Function pointer type for user-provided native function that handles the list
|
||||
|
@ -395,7 +369,7 @@ added: REPLACEME
|
|||
> Stability: 1 - Experimental
|
||||
|
||||
```c
|
||||
typedef node_embedding_exit_code(
|
||||
typedef node_embedding_status(
|
||||
NAPI_CDECL* node_embedding_configure_platform_callback)(
|
||||
void* cb_data,
|
||||
node_embedding_platform_config platform_config);
|
||||
|
@ -445,7 +419,7 @@ added: REPLACEME
|
|||
Sets global custom error handler for the Node.js embedded code.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL
|
||||
node_embedding_status NAPI_CDECL
|
||||
node_embedding_on_error(node_embedding_error_handler error_handler,
|
||||
void* error_handler_data);
|
||||
```
|
||||
|
@ -455,7 +429,7 @@ node_embedding_on_error(node_embedding_error_handler error_handler,
|
|||
passed to the `error_handler` callback. It can be removed after the
|
||||
`node_embedding_delete_platform()` call.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
It is recommended to call this function before the creation of the
|
||||
`node_embedding_platform` instance to handle all error messages the same way.
|
||||
|
@ -479,7 +453,7 @@ Sets the versions of the C embedding API and the Node-API.
|
|||
By default the API uses the latest stable versions of the APIs.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL node_embedding_set_api_version(
|
||||
node_embedding_status NAPI_CDECL node_embedding_set_api_version(
|
||||
int32_t embedding_api_version,
|
||||
int32_t node_api_version);
|
||||
```
|
||||
|
@ -487,7 +461,7 @@ node_embedding_exit_code NAPI_CDECL node_embedding_set_api_version(
|
|||
- `[in] embedding_api_version`: The version of the embedding API.
|
||||
- `[in] node_api_version`: The version of the Node-API.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
##### `node_embedding_run_main`
|
||||
|
||||
|
@ -502,7 +476,7 @@ It allows to customize the platform, the runtime, and evaluate some Node-API
|
|||
code after the runtime initialization.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL node_embedding_run_main(
|
||||
node_embedding_status NAPI_CDECL node_embedding_run_main(
|
||||
int32_t argc,
|
||||
char* argv[],
|
||||
node_embedding_configure_platform_callback configure_platform_cb,
|
||||
|
@ -525,7 +499,7 @@ node_embedding_exit_code NAPI_CDECL node_embedding_run_main(
|
|||
runtime initialization.
|
||||
- `[in] node_api_cb_data`: Additional data for the `node_api_cb` callback.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
##### `node_embedding_create_platform`
|
||||
|
||||
|
@ -538,7 +512,7 @@ added: REPLACEME
|
|||
Creates new Node.js platform instance.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL node_embedding_create_platform(
|
||||
node_embedding_status NAPI_CDECL node_embedding_create_platform(
|
||||
int32_t argc,
|
||||
char* argv[],
|
||||
node_embedding_configure_platform_callback configure_platform_cb,
|
||||
|
@ -553,7 +527,7 @@ node_embedding_exit_code NAPI_CDECL node_embedding_create_platform(
|
|||
`configure_platform_cb` callback.
|
||||
- `[out] result`: New Node.js platform instance.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
Node.js allows only a single platform instance per process.
|
||||
|
||||
|
@ -568,13 +542,13 @@ added: REPLACEME
|
|||
Deletes Node.js platform instance.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL
|
||||
node_embedding_status NAPI_CDECL
|
||||
node_embedding_delete_platform(node_embedding_platform platform);
|
||||
```
|
||||
|
||||
- `[in] platform`: The Node.js platform instance to delete.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
If the platform was initialized before the deletion, then the method
|
||||
uninitializes the platform before deletion.
|
||||
|
@ -590,7 +564,7 @@ added: REPLACEME
|
|||
Sets the Node.js platform instance flags.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL
|
||||
node_embedding_status NAPI_CDECL
|
||||
node_embedding_platform_set_flags(
|
||||
node_embedding_platform_config platform_config,
|
||||
node_embedding_platform_flags flags);
|
||||
|
@ -599,7 +573,7 @@ node_embedding_platform_set_flags(
|
|||
- `[in] platform_config`: The Node.js platform configuration.
|
||||
- `[in] flags`: The platform flags that control the platform behavior.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
##### `node_embedding_platform_get_parsed_args`
|
||||
|
||||
|
@ -612,7 +586,7 @@ added: REPLACEME
|
|||
Gets the parsed list of non-Node.js arguments.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL
|
||||
node_embedding_status NAPI_CDECL
|
||||
node_embedding_platform_get_parsed_args(
|
||||
node_embedding_platform platform,
|
||||
node_embedding_get_args_callback get_args_cb,
|
||||
|
@ -630,7 +604,7 @@ node_embedding_platform_get_parsed_args(
|
|||
to the `get_exec_args_cb` callback. It can be deleted right after the function
|
||||
call.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
### Runtime instance APIs
|
||||
|
||||
|
@ -744,7 +718,7 @@ added: REPLACEME
|
|||
> Stability: 1 - Experimental
|
||||
|
||||
```c
|
||||
typedef node_embedding_exit_code(
|
||||
typedef node_embedding_status(
|
||||
NAPI_CDECL* node_embedding_configure_runtime_callback)(
|
||||
void* cb_data,
|
||||
node_embedding_platform platform,
|
||||
|
@ -864,7 +838,7 @@ Runs Node.js runtime environment. It allows to customize the runtime, and
|
|||
evaluate some Node-API code after the runtime initialization.
|
||||
|
||||
```c
|
||||
NAPI_EXTERN node_embedding_exit_code NAPI_CDECL node_embedding_run_runtime(
|
||||
NAPI_EXTERN node_embedding_status NAPI_CDECL node_embedding_run_runtime(
|
||||
node_embedding_platform platform,
|
||||
node_embedding_configure_runtime_callback configure_runtime_cb,
|
||||
void* configure_runtime_cb_data,
|
||||
|
@ -880,7 +854,7 @@ NAPI_EXTERN node_embedding_exit_code NAPI_CDECL node_embedding_run_runtime(
|
|||
runtime initialization.
|
||||
- `[in] node_api_cb_data`: Additional data for the `node_api_cb` callback.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
##### `node_embedding_create_runtime`
|
||||
|
||||
|
@ -893,7 +867,7 @@ added: REPLACEME
|
|||
Creates new Node.js runtime instance.
|
||||
|
||||
```c
|
||||
NAPI_EXTERN node_embedding_exit_code NAPI_CDECL node_embedding_create_runtime(
|
||||
NAPI_EXTERN node_embedding_status NAPI_CDECL node_embedding_create_runtime(
|
||||
node_embedding_platform platform,
|
||||
node_embedding_configure_runtime_callback configure_runtime_cb,
|
||||
void* configure_runtime_cb_data,
|
||||
|
@ -906,7 +880,7 @@ NAPI_EXTERN node_embedding_exit_code NAPI_CDECL node_embedding_create_runtime(
|
|||
`configure_runtime_cb` callback.
|
||||
- `[out] result`: Upon return has a new Node.js runtime instance.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
Creates new Node.js runtime instance based on the provided platform instance.
|
||||
|
||||
|
@ -921,13 +895,13 @@ added: REPLACEME
|
|||
Deletes Node.js runtime instance.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL
|
||||
node_embedding_status NAPI_CDECL
|
||||
node_embedding_delete_runtime(node_embedding_runtime runtime);
|
||||
```
|
||||
|
||||
- `[in] runtime`: The Node.js runtime instance to delete.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
If the runtime was initialized, then the method un-initializes the runtime
|
||||
before the deletion.
|
||||
|
@ -947,7 +921,7 @@ added: REPLACEME
|
|||
Sets the Node.js runtime instance flags.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL
|
||||
node_embedding_status NAPI_CDECL
|
||||
node_embedding_runtime_set_flags(node_embedding_runtime_config runtime_config,
|
||||
node_embedding_runtime_flags flags);
|
||||
```
|
||||
|
@ -955,14 +929,14 @@ node_embedding_runtime_set_flags(node_embedding_runtime_config runtime_config,
|
|||
- `[in] runtime_config`: The Node.js runtime configuration.
|
||||
- `[in] flags`: The runtime flags that control the runtime behavior.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
##### `node_embedding_runtime_set_args`
|
||||
|
||||
Sets the non-Node.js arguments for the Node.js runtime instance.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL
|
||||
node_embedding_status NAPI_CDECL
|
||||
node_embedding_runtime_set_args(node_embedding_runtime_config runtime_config,
|
||||
int32_t argc,
|
||||
const char* argv[],
|
||||
|
@ -976,7 +950,7 @@ node_embedding_runtime_set_args(node_embedding_runtime_config runtime_config,
|
|||
- `[in] exec_argc`: Number of items in the `exec_argv` array.
|
||||
- `[in] exec_argv`: Node.js arguments as an array of zero terminating strings.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
##### `node_embedding_runtime_on_preload`
|
||||
|
||||
|
@ -989,7 +963,7 @@ added: REPLACEME
|
|||
Sets a preload callback to call before Node.js runtime instance is loaded.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL
|
||||
node_embedding_status NAPI_CDECL
|
||||
node_embedding_runtime_on_preload(
|
||||
node_embedding_runtime_config runtime_config,
|
||||
node_embedding_runtime_preload_callback preload_cb,
|
||||
|
@ -1003,7 +977,7 @@ node_embedding_runtime_on_preload(
|
|||
passed to the `preload_cb` callback. It can be removed after the
|
||||
`node_embedding_delete_runtime` call.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
##### `node_embedding_runtime_on_start_execution`
|
||||
|
||||
|
@ -1017,7 +991,7 @@ Sets a start execution callback to call when Node.js runtime instance
|
|||
starts execution.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL
|
||||
node_embedding_status NAPI_CDECL
|
||||
node_embedding_runtime_on_start_execution(
|
||||
node_embedding_runtime_config runtime_config,
|
||||
node_embedding_start_execution_callback start_execution_cb,
|
||||
|
@ -1031,7 +1005,7 @@ node_embedding_runtime_on_start_execution(
|
|||
that will be passed to the `start_execution_cb` callback. It can be removed
|
||||
after the `node_embedding_delete_runtime` call.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
##### `node_embedding_runtime_add_module`
|
||||
|
||||
|
@ -1044,12 +1018,11 @@ added: REPLACEME
|
|||
Adds a linked module for the Node.js runtime instance.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL
|
||||
node_embedding_status NAPI_CDECL
|
||||
node_embedding_runtime_add_module(
|
||||
node_embedding_runtime_config runtime_config,
|
||||
const char* module_name,
|
||||
node_embedding_initialize_module_callback init_module_cb,
|
||||
void* init_module_cb_data,
|
||||
node_embedding_initialize_module_functor init_module,
|
||||
int32_t module_node_api_version);
|
||||
```
|
||||
|
||||
|
@ -1060,7 +1033,7 @@ node_embedding_runtime_add_module(
|
|||
- `[in] init_module_cb_data`: The user data for the init_module_cb.
|
||||
- `[in] module_node_api_version`: The Node API version used by the module.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
The registered module can be accessed in JavaScript as
|
||||
`process._linkedBinding(module_name)` in the main JS and in the related
|
||||
|
@ -1082,25 +1055,25 @@ The event loop run mode.
|
|||
|
||||
```c
|
||||
typedef enum {
|
||||
node_embedding_event_loop_run_default = 0,
|
||||
node_embedding_event_loop_run_once = 1,
|
||||
node_embedding_event_loop_run_nowait = 2,
|
||||
node_embedding_event_loop_run_mode_default = 0,
|
||||
node_embedding_event_loop_run_mode_once = 1,
|
||||
node_embedding_event_loop_run_mode_nowait = 2,
|
||||
} node_embedding_event_loop_run_mode;
|
||||
```
|
||||
|
||||
These values match to UV library `uv_run_mode` enum and control the event loop
|
||||
behavior.
|
||||
|
||||
- `node_embedding_event_loop_run_default` - RRun the event loop until it is
|
||||
- `node_embedding_event_loop_run_mode_default` - RRun the event loop until it is
|
||||
completed. It matches the `UV_RUN_DEFAULT` behavior.
|
||||
- `node_embedding_event_loop_run_once` - Run the event loop once and wait if
|
||||
there are no items. It matches the `UV_RUN_ONCE` behavior.
|
||||
- `node_embedding_event_loop_run_nowait` - Run the event loop once and do not
|
||||
wait if there are no items. It matches the `UV_RUN_NOWAIT` behavior.
|
||||
- `node_embedding_event_loop_run_mode_once` - Run the event loop once and wait
|
||||
if there are no events. It matches the `UV_RUN_ONCE` behavior.
|
||||
- `node_embedding_event_loop_run_mode_nowait` - Run the event loop once and do
|
||||
not wait if there are no events. It matches the `UV_RUN_NOWAIT` behavior.
|
||||
|
||||
#### Callback types
|
||||
|
||||
##### `node_embedding_event_loop_handler`
|
||||
##### `node_embedding_post_task_callback`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
|
@ -1109,22 +1082,20 @@ added: REPLACEME
|
|||
> Stability: 1 - Experimental
|
||||
|
||||
```c
|
||||
typedef void(NAPI_CDECL* node_embedding_event_loop_handler)(
|
||||
node_embedding_runtime runtime,
|
||||
void* handler_data);
|
||||
typedef void(NAPI_CDECL* node_embedding_post_task_callback)(
|
||||
void* cb_data,
|
||||
node_embedding_run_task_functor run_task);
|
||||
```
|
||||
|
||||
Function pointer type for a handler that is called from the event loop observer
|
||||
thread when the runtime event loop has some work to do.
|
||||
Function pointer type for the `node_embedding_post_task_functor` that posts
|
||||
a task to the task runner.
|
||||
|
||||
The callback parameters:
|
||||
|
||||
- `[in] runtime`: The runtime owning the callback.
|
||||
- `[in] handler_data`: The data associated with the callback.
|
||||
- `[in] cb_data`: The data associated with the callback.
|
||||
- `[in] run_task`: The task to run in the task runner.
|
||||
|
||||
#### Functions
|
||||
|
||||
##### `node_embedding_on_wake_up_event_loop`
|
||||
##### `node_embedding_run_task_callback`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
|
@ -1132,29 +1103,105 @@ added: REPLACEME
|
|||
|
||||
> Stability: 1 - Experimental
|
||||
|
||||
Configures the runtime event loop to use a separate observer thread that calls
|
||||
the `event_loop_handler` when the runtime event loop has some work to do.
|
||||
```c
|
||||
typedef void(NAPI_CDECL* node_embedding_run_task_callback)(
|
||||
void* cb_data);
|
||||
```
|
||||
|
||||
Function pointer type for the `node_embedding_run_task_functor` that runs
|
||||
a task by the task runner.
|
||||
|
||||
The callback parameters:
|
||||
|
||||
- `[in] cb_data`: The data associated with the callback.
|
||||
|
||||
#### Functor types
|
||||
|
||||
##### `node_embedding_post_task_functor`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
> Stability: 1 - Experimental
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL
|
||||
node_embedding_on_wake_up_event_loop(
|
||||
typedef struct {
|
||||
void* data;
|
||||
node_embedding_post_task_callback invoke;
|
||||
node_embedding_release_data_callback release;
|
||||
} node_embedding_post_task_functor;
|
||||
```
|
||||
|
||||
Functor posts a task to a task runner.
|
||||
|
||||
The functor fields:
|
||||
|
||||
- `data`: The data associated with the functor.
|
||||
- `invoke`: The callback with this functor.
|
||||
- `release`: The callback to delete the `data` associated with this functor.
|
||||
|
||||
##### `node_embedding_run_task_functor`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
> Stability: 1 - Experimental
|
||||
|
||||
```c
|
||||
typedef struct {
|
||||
void* data;
|
||||
node_embedding_run_task_callback invoke;
|
||||
node_embedding_release_data_callback release;
|
||||
} node_embedding_run_task_functor;
|
||||
```
|
||||
|
||||
Functor that runs a task.
|
||||
|
||||
The functor fields:
|
||||
|
||||
- `data`: The data associated with the functor.
|
||||
- `invoke`: The callback with this functor.
|
||||
- `release`: The callback to delete the `data` associated with this functor.
|
||||
|
||||
#### Functions
|
||||
|
||||
##### `node_embedding_runtime_set_task_runner`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
> Stability: 1 - Experimental
|
||||
|
||||
Sets the task runner for the Node.js runtime.
|
||||
It enables running Node.js event loop as a part of application UI event loop or
|
||||
dispatcher queue.
|
||||
|
||||
```c
|
||||
node_embedding_status NAPI_CDECL
|
||||
node_embedding_runtime_set_task_runner(
|
||||
node_embedding_runtime_config runtime_config,
|
||||
node_embedding_event_loop_handler event_loop_handler,
|
||||
void* event_loop_handler_data);
|
||||
node_embedding_post_task_functor post_task);
|
||||
```
|
||||
|
||||
- `[in] runtime_config`: The Node.js runtime configuration.
|
||||
- `[in] event_loop_handler`: The handler called from the observer thread when
|
||||
the runtime event loop has some work to do.
|
||||
- `[in] event_loop_handler_data`: The data associated with the
|
||||
`event_loop_handler`.
|
||||
- `[in] post_task`: The functor that is called by the Node.js runtime to run
|
||||
event loop iteration.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
This function enables running Node.js runtime event loop from the host
|
||||
application UI event loop. The `event_loop_handler` typically schedules work in
|
||||
the UI event loop that runs the Node.js event loop. The UI event loop thread and
|
||||
the observer thread can be stopped until they have something to process.
|
||||
application UI event loop or a dispatcher queue. Internally it creates a thread
|
||||
that observes new events to process by the event loop. Then, it posts a task
|
||||
to run the event loop once using the `post_task` functor.
|
||||
|
||||
Note that running the event loop in a dedicated thread is more efficient.
|
||||
This method can be used in scenarios when we must combine the Node.js event
|
||||
loop processing with the application UI event loop. It may be required when
|
||||
the application wants to run JavaScript code from the UI thread to interop with
|
||||
the native UI components.
|
||||
|
||||
##### `node_embedding_run_event_loop`
|
||||
|
||||
|
@ -1167,7 +1214,7 @@ added: REPLACEME
|
|||
Runs Node.js runtime instance event loop.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL
|
||||
node_embedding_status NAPI_CDECL
|
||||
node_embedding_run_event_loop(
|
||||
node_embedding_runtime runtime,
|
||||
node_embedding_event_loop_run_mode run_mode,
|
||||
|
@ -1178,7 +1225,7 @@ node_embedding_run_event_loop(
|
|||
- `[in] run_mode`: The mode for running the runtime event loop.
|
||||
- `[out] has_more_work`: `true` if the event loop has more work to do.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
The function does not complete the Node.js runtime event loop if there are no
|
||||
more tasks to run.
|
||||
|
@ -1192,30 +1239,51 @@ added: REPLACEME
|
|||
> Stability: 1 - Experimental
|
||||
|
||||
Completes the Node.js runtime instance event loop.
|
||||
It includes completing all current tasks, emitting `beforeExit` event,
|
||||
completing the new tasks if they added, and emitting `exit` event in the end.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL
|
||||
node_embedding_status NAPI_CDECL
|
||||
node_embedding_complete_event_loop(
|
||||
node_embedding_runtime runtime);
|
||||
```
|
||||
|
||||
- `[in] runtime`: The Node.js runtime instance.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
Note that if new tasks are added in the `beforeExit` event handler, then after
|
||||
processing these tasks, the `beforeExit` is raised again, and the loop is
|
||||
continued until the `beforeExit` stops producing new tasks. Only after that the
|
||||
`exit` event is emitted. No new tasks can be added in the `exit` event handler
|
||||
or after that.
|
||||
It completes all current tasks and emits `beforeExit` event.
|
||||
If new tasks are added, then it completes them and raises the `beforeExit` event
|
||||
again. The process repeats until the `beforeExit` event stops producing new
|
||||
tasks. After that it emits the `exit` event and ends the event loop processing.
|
||||
No new tasks can be added in the `exit` event handler or after that.
|
||||
|
||||
##### `node_embedding_terminate_event_loop`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
> Stability: 1 - Experimental
|
||||
|
||||
Terminates the Node.js runtime instance event loop.
|
||||
|
||||
```c
|
||||
node_embedding_status NAPI_CDECL
|
||||
node_embedding_terminate_event_loop(
|
||||
node_embedding_runtime runtime);
|
||||
```
|
||||
|
||||
- `[in] runtime`: The Node.js runtime instance.
|
||||
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
The event loop is stopped and cannot be resumed.
|
||||
No `beforeExit` or `exit` events are going to be raised.
|
||||
|
||||
### JavaScript/Native interop APIs
|
||||
|
||||
#### Callback types
|
||||
|
||||
##### `node_embedding_node_api_callback`
|
||||
##### `node_embedding_run_node_api_callback`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
|
@ -1224,9 +1292,9 @@ added: REPLACEME
|
|||
> Stability: 1 - Experimental
|
||||
|
||||
```c
|
||||
typedef void(NAPI_CDECL* node_embedding_node_api_callback)(
|
||||
node_embedding_runtime runtime
|
||||
typedef void(NAPI_CDECL* node_embedding_run_node_api_callback)(
|
||||
void* cb_data,
|
||||
node_embedding_runtime runtime,
|
||||
napi_env env);
|
||||
```
|
||||
|
||||
|
@ -1234,10 +1302,34 @@ Function pointer type for callback that invokes Node-API code.
|
|||
|
||||
The callback parameters:
|
||||
|
||||
- `[in] runtime`: The Node.js runtime invoking this callback.
|
||||
- `[in] cb_data`: The user data associated with this callback.
|
||||
- `[in] runtime`: The Node.js runtime invoking this callback.
|
||||
- `[in] env`: Node-API environment.
|
||||
|
||||
#### Functor types
|
||||
|
||||
##### `node_embedding_run_node_api_functor_ref`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
> Stability: 1 - Experimental
|
||||
|
||||
```c
|
||||
typedef struct {
|
||||
void* data;
|
||||
node_embedding_run_node_api_callback invoke;
|
||||
} node_embedding_run_node_api_functor_ref;
|
||||
```
|
||||
|
||||
Functor reference that invokes Node-API code.
|
||||
|
||||
The functor reference fields:
|
||||
|
||||
- `data`: The data associated with the functor reference.
|
||||
- `invoke`: The callback with this functor reference.
|
||||
|
||||
#### Functions
|
||||
|
||||
##### `node_embedding_run_node_api`
|
||||
|
@ -1248,21 +1340,19 @@ added: REPLACEME
|
|||
|
||||
> Stability: 1 - Experimental
|
||||
|
||||
Invokes a callback that runs Node-API code.
|
||||
Runs Node-API code.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL
|
||||
node_embedding_status NAPI_CDECL
|
||||
node_embedding_run_node_api(
|
||||
node_embedding_runtime runtime,
|
||||
node_embedding_node_api_callback node_api_cb,
|
||||
void* node_api_cb_data);
|
||||
node_embedding_run_node_api_functor_ref run_node_api);
|
||||
```
|
||||
|
||||
- `[in] runtime`: The Node.js embedding_runtime instance.
|
||||
- `[in] node_api_cb`: The callback that executes Node-API code.
|
||||
- `[in] node_api_cb_data`: The data associated with the callback.
|
||||
- `[in] run_node_api`: The functor reference that invokes Node-API code.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
The function invokes the callback that runs Node-API code in the Node-API scope.
|
||||
Then, it triggers the uncaught exception handler if there were any
|
||||
|
@ -1279,19 +1369,21 @@ added: REPLACEME
|
|||
Opens scope to run Node-API code.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL
|
||||
node_embedding_status NAPI_CDECL
|
||||
node_embedding_open_node_api_scope(
|
||||
node_embedding_runtime runtime,
|
||||
node_embedding_node_api_scope* node_api_scope,
|
||||
napi_env* env);
|
||||
```
|
||||
|
||||
- `[in] runtime`: The Node.js embedding_runtime instance.
|
||||
- `[out] node_api_scope`: The opened Node-API scope.
|
||||
- `[out] env`: The Node-API environment that can be used in the scope.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
The function opens up V8 Isolate, V8 handle, and V8 context scopes where it is
|
||||
safe to the the Node-API environment.
|
||||
safe to run the Node-API environment.
|
||||
|
||||
##### `node_embedding_close_node_api_scope`
|
||||
|
||||
|
@ -1301,17 +1393,19 @@ added: REPLACEME
|
|||
|
||||
> Stability: 1 - Experimental
|
||||
|
||||
Opens scope to run Node-API code.
|
||||
Closes the Node-API invocation scope.
|
||||
|
||||
```c
|
||||
node_embedding_exit_code NAPI_CDECL
|
||||
node_embedding_status NAPI_CDECL
|
||||
node_embedding_close_node_api_scope(
|
||||
node_embedding_runtime runtime);
|
||||
node_embedding_runtime runtime,
|
||||
node_embedding_node_api_scope node_api_scope);
|
||||
```
|
||||
|
||||
- `[in] runtime`: The Node.js embedding_runtime instance.
|
||||
- `[in] node_api_scope`: The Node-API scope to close.
|
||||
|
||||
Returns `node_embedding_exit_code_ok` if there were no issues.
|
||||
Returns `node_embedding_status_ok` if there were no issues.
|
||||
|
||||
The function closes the V8 Isolate, V8 handle, and V8 context scopes.
|
||||
Then, it triggers the uncaught exception handler if there were any
|
||||
|
|
14
node.gyp
14
node.gyp
|
@ -1276,13 +1276,15 @@
|
|||
'sources': [
|
||||
'src/node_snapshot_stub.cc',
|
||||
'test/embedding/embedtest.cc',
|
||||
'test/embedding/embedtest_c_api.cc',
|
||||
'test/embedding/embedtest_c_api_common.cc',
|
||||
'test/embedding/embedtest_c_api_common.h',
|
||||
'test/embedding/embedtest_c_api_env.cc',
|
||||
'test/embedding/embedtest_c_api_modules.cc',
|
||||
'test/embedding/embedtest_c_api_preload.cc',
|
||||
'test/embedding/embedtest_c_api_run_main.cc',
|
||||
'test/embedding/embedtest_c_api_threading.cc',
|
||||
'test/embedding/embedtest_main.cc',
|
||||
'test/embedding/embedtest_modules_node_api.cc',
|
||||
'test/embedding/embedtest_node_api.cc',
|
||||
'test/embedding/embedtest_node_api.h',
|
||||
'test/embedding/embedtest_nodejs_main_node_api.cc',
|
||||
'test/embedding/embedtest_preload_node_api.cc',
|
||||
'test/embedding/embedtest_threading_node_api.cc',
|
||||
],
|
||||
|
||||
'conditions': [
|
||||
|
|
|
@ -88,27 +88,28 @@ struct napi_env__ {
|
|||
template <typename Call, typename JSExceptionHandler = decltype(HandleThrow)>
|
||||
inline void CallIntoModule(
|
||||
Call&& call, JSExceptionHandler&& handle_exception = HandleThrow) {
|
||||
CallModuleScope scope = OpenCallModuleScope();
|
||||
CallModuleScopeData scope_data = OpenCallModuleScope();
|
||||
auto onModuleScopeLeave = node::OnScopeLeave(
|
||||
[&] { CloseCallModuleScope(scope_data, handle_exception); });
|
||||
call(this);
|
||||
CloseCallModuleScope(scope, handle_exception);
|
||||
}
|
||||
|
||||
struct CallModuleScope {
|
||||
struct CallModuleScopeData {
|
||||
int open_handle_scopes_before;
|
||||
int open_callback_scopes_before;
|
||||
};
|
||||
|
||||
inline CallModuleScope OpenCallModuleScope() {
|
||||
inline CallModuleScopeData OpenCallModuleScope() {
|
||||
napi_clear_last_error(this);
|
||||
return {open_handle_scopes, open_callback_scopes};
|
||||
}
|
||||
|
||||
template <typename JSExceptionHandler = decltype(HandleThrow)>
|
||||
inline void CloseCallModuleScope(
|
||||
const CallModuleScope& scope,
|
||||
const CallModuleScopeData& scope_data,
|
||||
JSExceptionHandler&& handle_exception = HandleThrow) {
|
||||
CHECK_EQ(open_handle_scopes, scope.open_handle_scopes_before);
|
||||
CHECK_EQ(open_callback_scopes, scope.open_callback_scopes_before);
|
||||
CHECK_EQ(open_handle_scopes, scope_data.open_handle_scopes_before);
|
||||
CHECK_EQ(open_callback_scopes, scope_data.open_callback_scopes_before);
|
||||
if (!last_exception.IsEmpty()) {
|
||||
handle_exception(this, last_exception.Get(this->isolate));
|
||||
last_exception.Reset();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,11 +26,13 @@ EXTERN_C_START
|
|||
// Data types
|
||||
//==============================================================================
|
||||
|
||||
typedef struct node_embedding_platform__* node_embedding_platform;
|
||||
typedef struct node_embedding_runtime__* node_embedding_runtime;
|
||||
typedef struct node_embedding_platform_config__* node_embedding_platform_config;
|
||||
typedef struct node_embedding_runtime_config__* node_embedding_runtime_config;
|
||||
typedef struct node_embedding_platform_s* node_embedding_platform;
|
||||
typedef struct node_embedding_runtime_s* node_embedding_runtime;
|
||||
typedef struct node_embedding_platform_config_s* node_embedding_platform_config;
|
||||
typedef struct node_embedding_runtime_config_s* node_embedding_runtime_config;
|
||||
typedef struct node_embedding_node_api_scope_s* node_embedding_node_api_scope;
|
||||
|
||||
// The status returned by the Node.js embedding API functions.
|
||||
typedef enum {
|
||||
node_embedding_status_ok = 0,
|
||||
node_embedding_status_generic_error = 1,
|
||||
|
@ -41,107 +43,113 @@ typedef enum {
|
|||
node_embedding_status_error_exit_code = 512,
|
||||
} node_embedding_status;
|
||||
|
||||
// The flags for the Node.js platform initialization.
|
||||
// They match the internal ProcessInitializationFlags::Flags enum.
|
||||
typedef enum {
|
||||
node_embedding_platform_no_flags = 0,
|
||||
node_embedding_platform_flags_none = 0,
|
||||
// Enable stdio inheritance, which is disabled by default.
|
||||
// This flag is also implied by
|
||||
// node_embedding_platform_no_stdio_initialization.
|
||||
node_embedding_platform_enable_stdio_inheritance = 1 << 0,
|
||||
// node_embedding_platform_flags_no_stdio_initialization.
|
||||
node_embedding_platform_flags_enable_stdio_inheritance = 1 << 0,
|
||||
// Disable reading the NODE_OPTIONS environment variable.
|
||||
node_embedding_platform_disable_node_options_env = 1 << 1,
|
||||
node_embedding_platform_flags_disable_node_options_env = 1 << 1,
|
||||
// Do not parse CLI options.
|
||||
node_embedding_platform_disable_cli_options = 1 << 2,
|
||||
node_embedding_platform_flags_disable_cli_options = 1 << 2,
|
||||
// Do not initialize ICU.
|
||||
node_embedding_platform_no_icu = 1 << 3,
|
||||
node_embedding_platform_flags_no_icu = 1 << 3,
|
||||
// Do not modify stdio file descriptor or TTY state.
|
||||
node_embedding_platform_no_stdio_initialization = 1 << 4,
|
||||
node_embedding_platform_flags_no_stdio_initialization = 1 << 4,
|
||||
// Do not register Node.js-specific signal handlers
|
||||
// and reset other signal handlers to default state.
|
||||
node_embedding_platform_no_default_signal_handling = 1 << 5,
|
||||
node_embedding_platform_flags_no_default_signal_handling = 1 << 5,
|
||||
// Do not initialize OpenSSL config.
|
||||
node_embedding_platform_no_init_openssl = 1 << 8,
|
||||
node_embedding_platform_flags_no_init_openssl = 1 << 8,
|
||||
// Do not initialize Node.js debugging based on environment variables.
|
||||
node_embedding_platform_no_parse_global_debug_variables = 1 << 9,
|
||||
node_embedding_platform_flags_no_parse_global_debug_variables = 1 << 9,
|
||||
// Do not adjust OS resource limits for this process.
|
||||
node_embedding_platform_no_adjust_resource_limits = 1 << 10,
|
||||
node_embedding_platform_flags_no_adjust_resource_limits = 1 << 10,
|
||||
// Do not map code segments into large pages for this process.
|
||||
node_embedding_platform_no_use_large_pages = 1 << 11,
|
||||
node_embedding_platform_flags_no_use_large_pages = 1 << 11,
|
||||
// Skip printing output for --help, --version, --v8-options.
|
||||
node_embedding_platform_no_print_help_or_version_output = 1 << 12,
|
||||
node_embedding_platform_flags_no_print_help_or_version_output = 1 << 12,
|
||||
// Initialize the process for predictable snapshot generation.
|
||||
node_embedding_platform_generate_predictable_snapshot = 1 << 14,
|
||||
node_embedding_platform_flags_generate_predictable_snapshot = 1 << 14,
|
||||
} node_embedding_platform_flags;
|
||||
|
||||
// The flags for the Node.js runtime initialization.
|
||||
// They match the internal EnvironmentFlags::Flags enum.
|
||||
typedef enum {
|
||||
node_embedding_runtime_no_flags = 0,
|
||||
node_embedding_runtime_flags_none = 0,
|
||||
// Use the default behavior for Node.js instances.
|
||||
node_embedding_runtime_default_flags = 1 << 0,
|
||||
node_embedding_runtime_flags_default = 1 << 0,
|
||||
// Controls whether this Environment is allowed to affect per-process state
|
||||
// (e.g. cwd, process title, uid, etc.).
|
||||
// This is set when using node_embedding_runtime_default_flags.
|
||||
node_embedding_runtime_owns_process_state = 1 << 1,
|
||||
// This is set when using node_embedding_runtime_flags_default.
|
||||
node_embedding_runtime_flags_owns_process_state = 1 << 1,
|
||||
// Set if this Environment instance is associated with the global inspector
|
||||
// handling code (i.e. listening on SIGUSR1).
|
||||
// This is set when using node_embedding_runtime_default_flags.
|
||||
node_embedding_runtime_owns_inspector = 1 << 2,
|
||||
// This is set when using node_embedding_runtime_flags_default.
|
||||
node_embedding_runtime_flags_owns_inspector = 1 << 2,
|
||||
// Set if Node.js should not run its own esm loader. This is needed by some
|
||||
// embedders, because it's possible for the Node.js esm loader to conflict
|
||||
// with another one in an embedder environment, e.g. Blink's in Chromium.
|
||||
node_embedding_runtime_no_register_esm_loader = 1 << 3,
|
||||
node_embedding_runtime_flags_no_register_esm_loader = 1 << 3,
|
||||
// Set this flag to make Node.js track "raw" file descriptors, i.e. managed
|
||||
// by fs.open() and fs.close(), and close them during
|
||||
// node_embedding_delete_runtime().
|
||||
node_embedding_runtime_track_unmanaged_fds = 1 << 4,
|
||||
node_embedding_runtime_flags_track_unmanaged_fds = 1 << 4,
|
||||
// Set this flag to force hiding console windows when spawning child
|
||||
// processes. This is usually used when embedding Node.js in GUI programs on
|
||||
// Windows.
|
||||
node_embedding_runtime_hide_console_windows = 1 << 5,
|
||||
node_embedding_runtime_flags_hide_console_windows = 1 << 5,
|
||||
// Set this flag to disable loading native addons via `process.dlopen`.
|
||||
// This environment flag is especially important for worker threads
|
||||
// so that a worker thread can't load a native addon even if `execArgv`
|
||||
// is overwritten and `--no-addons` is not specified but was specified
|
||||
// for this Environment instance.
|
||||
node_embedding_runtime_no_native_addons = 1 << 6,
|
||||
node_embedding_runtime_flags_no_native_addons = 1 << 6,
|
||||
// Set this flag to disable searching modules from global paths like
|
||||
// $HOME/.node_modules and $NODE_PATH. This is used by standalone apps that
|
||||
// do not expect to have their behaviors changed because of globally
|
||||
// installed modules.
|
||||
node_embedding_runtime_no_global_search_paths = 1 << 7,
|
||||
node_embedding_runtime_flags_no_global_search_paths = 1 << 7,
|
||||
// Do not export browser globals like setTimeout, console, etc.
|
||||
node_embedding_runtime_no_browser_globals = 1 << 8,
|
||||
node_embedding_runtime_flags_no_browser_globals = 1 << 8,
|
||||
// Controls whether or not the Environment should call V8Inspector::create().
|
||||
// This control is needed by embedders who may not want to initialize the V8
|
||||
// inspector in situations where one has already been created,
|
||||
// e.g. Blink's in Chromium.
|
||||
node_embedding_runtime_no_create_inspector = 1 << 9,
|
||||
node_embedding_runtime_flags_no_create_inspector = 1 << 9,
|
||||
// Controls whether or not the InspectorAgent for this Environment should
|
||||
// call StartDebugSignalHandler. This control is needed by embedders who may
|
||||
// not want to allow other processes to start the V8 inspector.
|
||||
node_embedding_runtime_no_start_debug_signal_handler = 1 << 10,
|
||||
node_embedding_runtime_flags_no_start_debug_signal_handler = 1 << 10,
|
||||
// Controls whether the InspectorAgent created for this Environment waits for
|
||||
// Inspector frontend events during the Environment creation. It's used to
|
||||
// call node::Stop(env) on a Worker thread that is waiting for the events.
|
||||
node_embedding_runtime_no_wait_for_inspector_frontend = 1 << 11
|
||||
node_embedding_runtime_flags_no_wait_for_inspector_frontend = 1 << 11
|
||||
} node_embedding_runtime_flags;
|
||||
|
||||
typedef enum {
|
||||
// Run the event loop until it is completed.
|
||||
// It matches the UV_RUN_DEFAULT behavior.
|
||||
node_embedding_event_loop_run_default = 0,
|
||||
node_embedding_event_loop_run_mode_default = 0,
|
||||
// Run the event loop once and wait if there are no items.
|
||||
// It matches the UV_RUN_ONCE behavior.
|
||||
node_embedding_event_loop_run_once = 1,
|
||||
node_embedding_event_loop_run_mode_once = 1,
|
||||
// Run the event loop once and do not wait if there are no items.
|
||||
// It matches the UV_RUN_NOWAIT behavior.
|
||||
node_embedding_event_loop_run_nowait = 2,
|
||||
node_embedding_event_loop_run_mode_nowait = 2,
|
||||
} node_embedding_event_loop_run_mode;
|
||||
|
||||
//==============================================================================
|
||||
// Callbacks
|
||||
//==============================================================================
|
||||
|
||||
typedef node_embedding_status(NAPI_CDECL* node_embedding_error_handler)(
|
||||
void* handler_data,
|
||||
typedef void(NAPI_CDECL* node_embedding_release_data_callback)(void* data);
|
||||
|
||||
typedef node_embedding_status(NAPI_CDECL* node_embedding_handle_error_callback)(
|
||||
void* cb_data,
|
||||
const char* messages[],
|
||||
size_t messages_size,
|
||||
node_embedding_status status);
|
||||
|
@ -175,6 +183,12 @@ typedef napi_value(NAPI_CDECL* node_embedding_start_execution_callback)(
|
|||
napi_value require,
|
||||
napi_value run_cjs);
|
||||
|
||||
typedef void(NAPI_CDECL* node_embedding_handle_result_callback)(
|
||||
void* cb_data,
|
||||
node_embedding_runtime runtime,
|
||||
napi_env env,
|
||||
napi_value value);
|
||||
|
||||
typedef napi_value(NAPI_CDECL* node_embedding_initialize_module_callback)(
|
||||
void* cb_data,
|
||||
node_embedding_runtime runtime,
|
||||
|
@ -182,14 +196,25 @@ typedef napi_value(NAPI_CDECL* node_embedding_initialize_module_callback)(
|
|||
const char* module_name,
|
||||
napi_value exports);
|
||||
|
||||
typedef void(NAPI_CDECL* node_embedding_event_loop_handler)(
|
||||
void* handler_data, node_embedding_runtime runtime);
|
||||
typedef void(NAPI_CDECL* node_embedding_run_task_callback)(void* cb_data);
|
||||
|
||||
typedef void(NAPI_CDECL* node_embedding_node_api_callback)(
|
||||
typedef struct {
|
||||
void* data;
|
||||
node_embedding_run_task_callback invoke;
|
||||
node_embedding_release_data_callback release;
|
||||
} node_embedding_run_task_functor;
|
||||
|
||||
typedef void(NAPI_CDECL* node_embedding_post_task_callback)(
|
||||
void* cb_data, node_embedding_run_task_functor run_task);
|
||||
|
||||
typedef void(NAPI_CDECL* node_embedding_run_node_api_callback)(
|
||||
void* cb_data, node_embedding_runtime runtime, napi_env env);
|
||||
|
||||
typedef void(NAPI_CDECL* node_embedding_release_callback)(
|
||||
void* data_to_release);
|
||||
typedef struct {
|
||||
void* data;
|
||||
node_embedding_handle_error_callback invoke;
|
||||
node_embedding_release_data_callback release;
|
||||
} node_embedding_handle_error_functor;
|
||||
|
||||
typedef struct {
|
||||
void* data;
|
||||
|
@ -203,8 +228,8 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
void* data;
|
||||
node_embedding_node_api_callback invoke;
|
||||
} node_embedding_node_api_functor_ref;
|
||||
node_embedding_run_node_api_callback invoke;
|
||||
} node_embedding_run_node_api_functor_ref;
|
||||
|
||||
typedef struct {
|
||||
void* data;
|
||||
|
@ -214,26 +239,32 @@ typedef struct {
|
|||
typedef struct {
|
||||
void* data;
|
||||
node_embedding_preload_callback invoke;
|
||||
node_embedding_release_callback release;
|
||||
node_embedding_release_data_callback release;
|
||||
} node_embedding_preload_functor;
|
||||
|
||||
typedef struct {
|
||||
void* data;
|
||||
node_embedding_start_execution_callback invoke;
|
||||
node_embedding_release_callback release;
|
||||
node_embedding_release_data_callback release;
|
||||
} node_embedding_start_execution_functor;
|
||||
|
||||
typedef struct {
|
||||
void* data;
|
||||
node_embedding_handle_result_callback invoke;
|
||||
node_embedding_release_data_callback release;
|
||||
} node_embedding_handle_result_functor;
|
||||
|
||||
typedef struct {
|
||||
void* data;
|
||||
node_embedding_initialize_module_callback invoke;
|
||||
node_embedding_release_callback release;
|
||||
node_embedding_release_data_callback release;
|
||||
} node_embedding_initialize_module_functor;
|
||||
|
||||
typedef struct {
|
||||
void* data;
|
||||
node_embedding_event_loop_handler invoke;
|
||||
node_embedding_release_callback release;
|
||||
} node_embedding_event_loop_functor;
|
||||
node_embedding_post_task_callback invoke;
|
||||
node_embedding_release_data_callback release;
|
||||
} node_embedding_post_task_functor;
|
||||
|
||||
//==============================================================================
|
||||
// Functions
|
||||
|
@ -244,8 +275,8 @@ typedef struct {
|
|||
//------------------------------------------------------------------------------
|
||||
|
||||
// Sets the global error handing for the Node.js embedding API.
|
||||
NAPI_EXTERN node_embedding_status NAPI_CDECL node_embedding_on_error(
|
||||
node_embedding_error_handler error_handler, void* error_handler_data);
|
||||
NAPI_EXTERN node_embedding_status NAPI_CDECL
|
||||
node_embedding_on_error(node_embedding_handle_error_functor error_handler);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Node.js global platform functions.
|
||||
|
@ -260,8 +291,7 @@ NAPI_EXTERN node_embedding_status NAPI_CDECL node_embedding_run_main(
|
|||
int32_t argc,
|
||||
char* argv[],
|
||||
node_embedding_configure_platform_functor_ref configure_platform,
|
||||
node_embedding_configure_runtime_functor_ref configure_runtime,
|
||||
node_embedding_node_api_functor_ref run_node_api);
|
||||
node_embedding_configure_runtime_functor_ref configure_runtime);
|
||||
|
||||
// Creates and configures a new Node.js platform instance.
|
||||
NAPI_EXTERN node_embedding_status NAPI_CDECL node_embedding_create_platform(
|
||||
|
@ -284,7 +314,7 @@ NAPI_EXTERN node_embedding_status NAPI_CDECL
|
|||
node_embedding_platform_get_parsed_args(
|
||||
node_embedding_platform platform,
|
||||
node_embedding_get_args_functor_ref get_args,
|
||||
node_embedding_get_args_functor_ref get_exec_args);
|
||||
node_embedding_get_args_functor_ref get_runtime_args);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Node.js runtime functions.
|
||||
|
@ -293,8 +323,7 @@ node_embedding_platform_get_parsed_args(
|
|||
// Runs the Node.js runtime with the provided configuration.
|
||||
NAPI_EXTERN node_embedding_status NAPI_CDECL node_embedding_run_runtime(
|
||||
node_embedding_platform platform,
|
||||
node_embedding_configure_runtime_functor_ref configure_runtime,
|
||||
node_embedding_node_api_functor_ref run_node_api);
|
||||
node_embedding_configure_runtime_functor_ref configure_runtime);
|
||||
|
||||
// Creates a new Node.js runtime instance.
|
||||
NAPI_EXTERN node_embedding_status NAPI_CDECL node_embedding_create_runtime(
|
||||
|
@ -317,8 +346,8 @@ NAPI_EXTERN node_embedding_status NAPI_CDECL
|
|||
node_embedding_runtime_set_args(node_embedding_runtime_config runtime_config,
|
||||
int32_t argc,
|
||||
const char* argv[],
|
||||
int32_t exec_argc,
|
||||
const char* exec_argv[]);
|
||||
int32_t runtime_argc,
|
||||
const char* runtime_argv[]);
|
||||
|
||||
// Sets the preload callback for the Node.js runtime initialization.
|
||||
NAPI_EXTERN node_embedding_status NAPI_CDECL
|
||||
|
@ -329,7 +358,8 @@ node_embedding_runtime_on_preload(node_embedding_runtime_config runtime_config,
|
|||
NAPI_EXTERN node_embedding_status NAPI_CDECL
|
||||
node_embedding_runtime_on_start_execution(
|
||||
node_embedding_runtime_config runtime_config,
|
||||
node_embedding_start_execution_functor start_execution);
|
||||
node_embedding_start_execution_functor start_execution,
|
||||
node_embedding_handle_result_functor handle_result);
|
||||
|
||||
// Adds a new module to the Node.js runtime.
|
||||
// It is accessed as process._linkedBinding(module_name) in the main JS and in
|
||||
|
@ -344,14 +374,15 @@ NAPI_EXTERN node_embedding_status NAPI_CDECL node_embedding_runtime_add_module(
|
|||
// Node.js runtime functions for the event loop.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Initializes the runtime to call the provided handler when the runtime event
|
||||
// loop has some work to do. It starts an observer thread that is stopped by the
|
||||
// `node_embedding_runtime_complete_event_loop` function call. This function
|
||||
// helps to integrate the Node.js runtime event loop with the host UI loop.
|
||||
// Sets the task runner for the Node.js runtime.
|
||||
// This is an alternative way to run the Node.js runtime event loop that helps
|
||||
// running it inside of an existing task scheduler.
|
||||
// E.g. it enables running Node.js event loop inside of the application UI event
|
||||
// loop or UI dispatcher.
|
||||
NAPI_EXTERN node_embedding_status NAPI_CDECL
|
||||
node_embedding_on_wake_up_event_loop(
|
||||
node_embedding_runtime_set_task_runner(
|
||||
node_embedding_runtime_config runtime_config,
|
||||
node_embedding_event_loop_functor run_event_loop);
|
||||
node_embedding_post_task_functor post_task);
|
||||
|
||||
// Runs the Node.js runtime event loop.
|
||||
NAPI_EXTERN node_embedding_status NAPI_CDECL
|
||||
|
@ -364,27 +395,46 @@ node_embedding_run_event_loop(node_embedding_runtime runtime,
|
|||
NAPI_EXTERN node_embedding_status NAPI_CDECL
|
||||
node_embedding_complete_event_loop(node_embedding_runtime runtime);
|
||||
|
||||
// Stops the Node.js runtime event loop. It cannot be resumed after this call.
|
||||
NAPI_EXTERN node_embedding_status NAPI_CDECL
|
||||
node_embedding_terminate_event_loop(node_embedding_runtime runtime);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Node.js runtime functions for the Node-API interop.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Runs Node-API code.
|
||||
NAPI_EXTERN node_embedding_status NAPI_CDECL
|
||||
node_embedding_run_node_api(node_embedding_runtime runtime,
|
||||
node_embedding_node_api_functor_ref run_node_api);
|
||||
// Runs Node-API code in the Node-API scope.
|
||||
NAPI_EXTERN node_embedding_status NAPI_CDECL node_embedding_run_node_api(
|
||||
node_embedding_runtime runtime,
|
||||
node_embedding_run_node_api_functor_ref run_node_api);
|
||||
|
||||
// Opens a new Node-API scope.
|
||||
NAPI_EXTERN node_embedding_status NAPI_CDECL node_embedding_open_node_api_scope(
|
||||
node_embedding_runtime runtime, napi_env* env);
|
||||
node_embedding_runtime runtime,
|
||||
node_embedding_node_api_scope* node_api_scope,
|
||||
napi_env* env);
|
||||
|
||||
// Closes the current Node-API scope.
|
||||
// Closes the Node-API invocation scope.
|
||||
NAPI_EXTERN node_embedding_status NAPI_CDECL
|
||||
node_embedding_close_node_api_scope(node_embedding_runtime runtime);
|
||||
node_embedding_close_node_api_scope(
|
||||
node_embedding_runtime runtime,
|
||||
node_embedding_node_api_scope node_api_scope);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
//==============================================================================
|
||||
// C++ convenience functions for the C API.
|
||||
// These functions are not ABI safe and can be changed in future versions.
|
||||
//==============================================================================
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
namespace node {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Convenience union operator for the Node.js flags.
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -401,6 +451,125 @@ inline constexpr node_embedding_runtime_flags operator|(
|
|||
static_cast<int32_t>(rhs));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Convenience functor struct adapter for C++ function object or lambdas.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace details {
|
||||
|
||||
template <typename TLambda, typename TFunctor>
|
||||
struct FunctorAdapter {
|
||||
static_assert(sizeof(TLambda) == -1, "Unsupported signature");
|
||||
};
|
||||
|
||||
template <typename TLambda, typename TResult, typename... TArgs>
|
||||
struct FunctorAdapter<TLambda, TResult(void*, TArgs...)> {
|
||||
static TResult Invoke(void* data, TArgs... args) {
|
||||
return reinterpret_cast<TLambda*>(data)->operator()(args...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TLambda, typename... TArgs>
|
||||
struct FunctorAdapter<TLambda, void(void*, TArgs...)> {
|
||||
static void Invoke(void* data, TArgs... args) {
|
||||
reinterpret_cast<TLambda*>(data)->operator()(args...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct FunctorDeleter {
|
||||
void operator()(T* ptr) {
|
||||
if (ptr->release != nullptr) {
|
||||
ptr->release(ptr->data);
|
||||
}
|
||||
delete ptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TFunctor>
|
||||
struct StdFunctionAdapter {
|
||||
static_assert(sizeof(TFunctor) == -1, "Unsupported signature");
|
||||
};
|
||||
|
||||
template <typename TResult, typename... TArgs>
|
||||
struct StdFunctionAdapter<TResult(void*, TArgs...)> {
|
||||
using FunctionType = std::function<TResult(TArgs...)>;
|
||||
|
||||
template <typename TFunctorSharedPtr>
|
||||
static FunctionType Create(TFunctorSharedPtr&& ptr) {
|
||||
return ptr ? FunctionType([ptr = std::move(ptr)](TArgs... args) {
|
||||
return ptr->invoke(ptr->data, args...);
|
||||
})
|
||||
: FunctionType(nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... TArgs>
|
||||
struct StdFunctionAdapter<void(void*, TArgs...)> {
|
||||
using FunctionType = std::function<void(TArgs...)>;
|
||||
|
||||
template <typename TFunctorSharedPtr>
|
||||
static FunctionType Create(TFunctorSharedPtr&& ptr) {
|
||||
return ptr ? FunctionType([ptr = std::move(ptr)](TArgs... args) {
|
||||
ptr->invoke(ptr->data, args...);
|
||||
})
|
||||
: FunctionType(nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
template <typename TFunctor, typename TLambda>
|
||||
inline TFunctor AsFunctorRef(TLambda&& lambda) {
|
||||
using TLambdaType = std::remove_reference_t<TLambda>;
|
||||
using TAdapter = details::FunctorAdapter<
|
||||
TLambdaType,
|
||||
std::remove_pointer_t<
|
||||
decltype(std::remove_reference_t<TFunctor>::invoke)>>;
|
||||
return TFunctor{static_cast<void*>(&lambda), &TAdapter::Invoke};
|
||||
}
|
||||
|
||||
template <typename TFunctor, typename TLambda>
|
||||
inline TFunctor AsFunctor(TLambda&& lambda) {
|
||||
using TLambdaType = std::remove_reference_t<TLambda>;
|
||||
using TAdapter = details::FunctorAdapter<
|
||||
TLambdaType,
|
||||
std::remove_pointer_t<
|
||||
decltype(std::remove_reference_t<TFunctor>::invoke)>>;
|
||||
return TFunctor{
|
||||
static_cast<void*>(new TLambdaType(std::forward<TLambdaType>(lambda))),
|
||||
&TAdapter::Invoke,
|
||||
[](void* data) { delete static_cast<TLambdaType*>(data); }};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
using FunctorPtr = std::unique_ptr<T, details::FunctorDeleter<T>>;
|
||||
|
||||
template <typename T>
|
||||
FunctorPtr<T> MakeUniqueFunctorPtr(const T& functor) {
|
||||
return functor.invoke ? FunctorPtr<T>(new T(functor)) : nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<T> MakeSharedFunctorPtr(const T& functor) {
|
||||
return functor.invoke
|
||||
? std::shared_ptr<T>(new T(functor), details::FunctorDeleter<T>())
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
template <typename TFunctor>
|
||||
using StdFunction = typename details::StdFunctionAdapter<std::remove_pointer_t<
|
||||
decltype(std::remove_reference_t<TFunctor>::invoke)>>::FunctionType;
|
||||
|
||||
template <typename TFunctor>
|
||||
inline StdFunction<TFunctor> AsStdFunction(TFunctor&& functor) {
|
||||
using TAdapter = details::StdFunctionAdapter<std::remove_pointer_t<
|
||||
decltype(std::remove_reference_t<TFunctor>::invoke)>>;
|
||||
return TAdapter::Create(std::move(MakeSharedFunctorPtr(functor)));
|
||||
}
|
||||
|
||||
} // namespace node
|
||||
|
||||
#endif
|
||||
|
||||
#endif // SRC_NODE_EMBEDDING_API_H_
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# C embedding API
|
||||
|
||||
This file is an overview for C embedding API.
|
||||
It is mostly to catch all the work in progress notes.
|
||||
It is mostly to catch all the work in progress.
|
||||
|
||||
## The API overview
|
||||
|
||||
|
@ -40,32 +40,85 @@ It is mostly to catch all the work in progress notes.
|
|||
- `node_embedding_open_node_api_scope`
|
||||
- `node_embedding_close_node_api_scope`
|
||||
|
||||
### API TODOs
|
||||
## Functional overview
|
||||
|
||||
### Platform API
|
||||
|
||||
- Global handling of C API errors
|
||||
- [ ] Global handling of Node.js/V8 errors (is it possible?)
|
||||
- [ ] Global handling of unhandled JS errors
|
||||
|
||||
- API version
|
||||
- Node-API version
|
||||
|
||||
- Global platform initialization
|
||||
- Global platform uninitialization
|
||||
- Parsing the command line parameters
|
||||
- Controlled by the platform flags
|
||||
- Get parsed command line arguments
|
||||
|
||||
- [ ] Allow running Node.js uv_loop from UI loop. Follow the Electron
|
||||
implementation. - Complete implementation for non-Windows.
|
||||
- [ ] Can we use some kind of waiter concept instead of the
|
||||
observer thread?
|
||||
- [ ] Generate the main script based on the runtime settings.
|
||||
- [ ] Set the global Inspector for he main runtime.
|
||||
- [ ] Start workers from C++.
|
||||
- [ ] Worker to inherit parent Inspector.
|
||||
- [ ] Cancel pending event loop tasks on runtime deletion.
|
||||
- [ ] Can we initialize platform again if it returns early?
|
||||
- [ ] Test passing the V8 thread pool size.
|
||||
- [ ] Add a way to terminate the runtime.
|
||||
- [ ] Allow to provide custom thread pool from the app.
|
||||
- [ ] Consider adding a v-table for the API functions to simplify
|
||||
binding with other languages.
|
||||
- [ ] We must not exit the process on node::Environment errors.
|
||||
- [ ] Be explicit about the recoverable errors.
|
||||
- [ ] Store IsolateScope in TLS.
|
||||
- [-] Will not support: custom thread pool
|
||||
|
||||
- [ ] API v-table to avoid DLL named function binding
|
||||
|
||||
### Runtime API
|
||||
|
||||
- Runtime initialization
|
||||
- Runtime uninitialization
|
||||
- Set runtime args
|
||||
- Set runtime flags
|
||||
- Register a preload callback
|
||||
- Register start execution callback
|
||||
- [ ] Load default Node.js snapshot without the custom start execution callback
|
||||
- [ ] Get the returned value from the start execution
|
||||
- Register linked modules
|
||||
|
||||
- [ ] Runtime handling of API errors (is it possible?)
|
||||
- [ ] Runtime handling of Node.js/V8 errors (is it possible?)
|
||||
- [ ] Runtime handling of unhandled JS errors
|
||||
|
||||
- [ ] Events on Runtime destruction (beforeExit, exit)
|
||||
- [ ] Main vs secondary Runtimes
|
||||
- [ ] Worker thread runtimes (is it possible?)
|
||||
- [ ] Associate Inspector with the Runtime
|
||||
- [ ] Inspector for the secondary Runtimes
|
||||
- [ ] Runtime destructor to clean up all related resources including the
|
||||
pending tasks.
|
||||
- [ ] Exit process only for unhandled main runtime errors.
|
||||
- [ ] Have an internal list of all runtimes in the system.
|
||||
It is a list of all secondary runtimes attached to the main runtime.
|
||||
|
||||
### Event Loop API
|
||||
|
||||
- Run event loop while it has events (default)
|
||||
- Run event loop once and block for an event
|
||||
- Run event loop once and no wait
|
||||
- Run event loop till completion
|
||||
- [ ] Interrupt the event loop (uv_stop stops the default loop and then
|
||||
the loop resets it)
|
||||
- [ ] Loop while some condition is true
|
||||
- [ ] Custom foreground task runner (is it possible?)
|
||||
- [ ] Notify if event loop has work to do (based on Electron PollEvents)
|
||||
It must be blocked while the loop is running
|
||||
It is only for the main runtime
|
||||
- [ ] V8 Microtask posting and draining
|
||||
- [ ] Complete the loop immediately if needed
|
||||
- [ ] Protect from nested uv_run calls
|
||||
- [ ] How to post setImmediate from another thread?
|
||||
|
||||
### Node-API integration
|
||||
|
||||
- Run Node-API code as a lambda
|
||||
- Explicitly open and close the Node-API scope
|
||||
- [ ] Handle JS errors
|
||||
|
||||
### Test TODOs
|
||||
|
||||
- [ ] Test passing the V8 thread pool size.
|
||||
- [ ] Add tests based on the environment and platform `cctest`s.
|
||||
- [ ] Enable the test_main_modules_node_api test.
|
||||
- [ ] Test failure in Preload callback.
|
||||
- [ ] Test failure in linked modules.
|
||||
- [ ] Add a test that handles JS errors.
|
||||
- [ ] Make sure that the delete calls match the create calls.
|
||||
- [ ] Make sure that the the delete calls match the create calls.
|
||||
|
|
|
@ -1,21 +1,18 @@
|
|||
#include "embedtest_node_api.h"
|
||||
#include "embedtest_c_api_common.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
const char* main_script =
|
||||
"globalThis.require = require('module').createRequire(process.execPath);\n"
|
||||
"globalThis.embedVars = { nön_ascıı: '🏳️🌈' };\n"
|
||||
"require('vm').runInThisContext(process.argv[1]);";
|
||||
using namespace node;
|
||||
|
||||
void CallMe(node_embedding_runtime runtime, napi_env env);
|
||||
void WaitMe(node_embedding_runtime runtime, napi_env env);
|
||||
void WaitMeWithCheese(node_embedding_runtime runtime, napi_env env);
|
||||
|
||||
extern "C" int32_t test_main_node_api(int32_t argc, char* argv[]) {
|
||||
node_embedding_on_error(HandleTestError, argv[0]);
|
||||
node_embedding_on_error({argv[0], HandleTestError, nullptr});
|
||||
|
||||
CHECK_STATUS_OR_EXIT(node_embedding_run_main(
|
||||
argc,
|
||||
|
@ -24,92 +21,29 @@ extern "C" int32_t test_main_node_api(int32_t argc, char* argv[]) {
|
|||
[&](node_embedding_platform_config platform_config) {
|
||||
CHECK_STATUS(node_embedding_platform_set_flags(
|
||||
platform_config,
|
||||
node_embedding_platform_disable_node_options_env));
|
||||
node_embedding_platform_flags_disable_node_options_env));
|
||||
return node_embedding_status_ok;
|
||||
}),
|
||||
AsFunctorRef<node_embedding_configure_runtime_functor_ref>(
|
||||
[&](node_embedding_platform platform,
|
||||
node_embedding_runtime_config runtime_config) {
|
||||
CHECK_STATUS(node_embedding_runtime_on_start_execution(
|
||||
runtime_config,
|
||||
AsFunctor<node_embedding_start_execution_functor>(
|
||||
[](node_embedding_runtime runtime,
|
||||
napi_env env,
|
||||
napi_value process,
|
||||
napi_value require,
|
||||
napi_value run_cjs) -> napi_value {
|
||||
napi_status status{};
|
||||
napi_value script, undefined, result;
|
||||
NODE_API_CALL(napi_create_string_utf8(
|
||||
env, main_script, NAPI_AUTO_LENGTH, &script));
|
||||
NODE_API_CALL(napi_get_undefined(env, &undefined));
|
||||
NODE_API_CALL(napi_call_function(
|
||||
env, undefined, run_cjs, 1, &script, &result));
|
||||
return result;
|
||||
})));
|
||||
CHECK_STATUS(
|
||||
LoadUtf8Script(runtime_config,
|
||||
main_script,
|
||||
AsFunctor<node_embedding_handle_result_functor>(
|
||||
[&](node_embedding_runtime runtime,
|
||||
napi_env env,
|
||||
napi_value /*value*/) {
|
||||
CallMe(runtime, env);
|
||||
WaitMe(runtime, env);
|
||||
WaitMeWithCheese(runtime, env);
|
||||
})));
|
||||
return node_embedding_status_ok;
|
||||
}),
|
||||
AsFunctorRef<node_embedding_node_api_functor_ref>(
|
||||
[&](node_embedding_runtime runtime, napi_env env) {
|
||||
CallMe(runtime, env);
|
||||
WaitMe(runtime, env);
|
||||
WaitMeWithCheese(runtime, env);
|
||||
})));
|
||||
|
||||
return node_embedding_status_ok;
|
||||
}
|
||||
|
||||
napi_status AddUtf8String(std::string& str, napi_env env, napi_value value) {
|
||||
size_t str_size = 0;
|
||||
napi_status status =
|
||||
napi_get_value_string_utf8(env, value, nullptr, 0, &str_size);
|
||||
if (status != napi_ok) {
|
||||
return status;
|
||||
}
|
||||
size_t offset = str.size();
|
||||
str.resize(offset + str_size);
|
||||
status = napi_get_value_string_utf8(
|
||||
env, value, &str[0] + offset, str_size + 1, &str_size);
|
||||
return status;
|
||||
}
|
||||
|
||||
void GetAndThrowLastErrorMessage(napi_env env) {
|
||||
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 != nullptr ? err_message : "empty error message";
|
||||
napi_throw_error((env), nullptr, error_message);
|
||||
}
|
||||
}
|
||||
|
||||
void ThrowLastErrorMessage(napi_env env, const char* message) {
|
||||
bool is_pending;
|
||||
napi_is_exception_pending(env, &is_pending);
|
||||
/* If an exception is already pending, don't rethrow it */
|
||||
if (!is_pending) {
|
||||
const char* error_message =
|
||||
message != nullptr ? message : "empty error message";
|
||||
napi_throw_error(env, nullptr, error_message);
|
||||
}
|
||||
}
|
||||
|
||||
std::string FormatString(const char* format, ...) {
|
||||
va_list args1;
|
||||
va_start(args1, format);
|
||||
va_list args2;
|
||||
va_copy(args2, args1); // Required for some compilers like GCC.
|
||||
std::string result(std::vsnprintf(nullptr, 0, format, args1), '\0');
|
||||
va_end(args1);
|
||||
std::vsnprintf(&result[0], result.size() + 1, format, args2);
|
||||
va_end(args2);
|
||||
return result;
|
||||
}
|
||||
|
||||
void CallMe(node_embedding_runtime runtime, napi_env env) {
|
||||
napi_value global;
|
||||
napi_value cb;
|
||||
|
@ -190,7 +124,7 @@ void WaitMe(node_embedding_runtime runtime, napi_env env) {
|
|||
}
|
||||
|
||||
node_embedding_run_event_loop(
|
||||
runtime, node_embedding_event_loop_run_default, nullptr);
|
||||
runtime, node_embedding_event_loop_run_mode_default, nullptr);
|
||||
|
||||
if (strcmp(callback_buf, "waited you") != 0) {
|
||||
NODE_API_FAIL_RETURN_VOID("Invalid value received: %s\n", callback_buf);
|
||||
|
@ -291,7 +225,7 @@ void WaitMeWithCheese(node_embedding_runtime runtime, napi_env env) {
|
|||
|
||||
while (promise_state == PromiseState::kPending) {
|
||||
node_embedding_run_event_loop(
|
||||
runtime, node_embedding_event_loop_run_nowait, nullptr);
|
||||
runtime, node_embedding_event_loop_run_mode_nowait, nullptr);
|
||||
}
|
||||
|
||||
expected = (promise_state == PromiseState::kFulfilled)
|
|
@ -0,0 +1,87 @@
|
|||
#include "embedtest_c_api_common.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
using namespace node;
|
||||
|
||||
const char* main_script =
|
||||
"globalThis.require = require('module').createRequire(process.execPath);\n"
|
||||
"globalThis.embedVars = { nön_ascıı: '🏳️🌈' };\n"
|
||||
"require('vm').runInThisContext(process.argv[1]);";
|
||||
|
||||
napi_status AddUtf8String(std::string& str, napi_env env, napi_value value) {
|
||||
size_t str_size = 0;
|
||||
napi_status status =
|
||||
napi_get_value_string_utf8(env, value, nullptr, 0, &str_size);
|
||||
if (status != napi_ok) {
|
||||
return status;
|
||||
}
|
||||
size_t offset = str.size();
|
||||
str.resize(offset + str_size);
|
||||
status = napi_get_value_string_utf8(
|
||||
env, value, &str[0] + offset, str_size + 1, &str_size);
|
||||
return status;
|
||||
}
|
||||
|
||||
void GetAndThrowLastErrorMessage(napi_env env) {
|
||||
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 != nullptr ? err_message : "empty error message";
|
||||
napi_throw_error((env), nullptr, error_message);
|
||||
}
|
||||
}
|
||||
|
||||
void ThrowLastErrorMessage(napi_env env, const char* message) {
|
||||
bool is_pending;
|
||||
napi_is_exception_pending(env, &is_pending);
|
||||
/* If an exception is already pending, don't rethrow it */
|
||||
if (!is_pending) {
|
||||
const char* error_message =
|
||||
message != nullptr ? message : "empty error message";
|
||||
napi_throw_error(env, nullptr, error_message);
|
||||
}
|
||||
}
|
||||
|
||||
std::string FormatString(const char* format, ...) {
|
||||
va_list args1;
|
||||
va_start(args1, format);
|
||||
va_list args2;
|
||||
va_copy(args2, args1); // Required for some compilers like GCC.
|
||||
std::string result(std::vsnprintf(nullptr, 0, format, args1), '\0');
|
||||
va_end(args1);
|
||||
std::vsnprintf(&result[0], result.size() + 1, format, args2);
|
||||
va_end(args2);
|
||||
return result;
|
||||
}
|
||||
|
||||
node_embedding_status LoadUtf8Script(
|
||||
node_embedding_runtime_config runtime_config,
|
||||
std::string script,
|
||||
const node_embedding_handle_result_functor& handle_result) {
|
||||
return node_embedding_runtime_on_start_execution(
|
||||
runtime_config,
|
||||
AsFunctor<node_embedding_start_execution_functor>(
|
||||
[script = std::move(script)](node_embedding_runtime /*runtime*/,
|
||||
napi_env env,
|
||||
napi_value /*process*/,
|
||||
napi_value /*require*/,
|
||||
napi_value run_cjs) -> napi_value {
|
||||
napi_value script_value, null_value, result;
|
||||
NODE_API_CALL(napi_create_string_utf8(
|
||||
env, script.c_str(), script.size(), &script_value));
|
||||
NODE_API_CALL(napi_get_null(env, &null_value));
|
||||
NODE_API_CALL(napi_call_function(
|
||||
env, null_value, run_cjs, 1, &script_value, &result));
|
||||
return result;
|
||||
}),
|
||||
handle_result);
|
||||
}
|
|
@ -10,11 +10,37 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
extern "C" inline void NAPI_CDECL GetArgsVector(void* data,
|
||||
int32_t argc,
|
||||
const char* argv[]) {
|
||||
static_cast<std::vector<std::string>*>(data)->assign(argv, argv + argc);
|
||||
}
|
||||
template <size_t kInplaceBufferSize = 32>
|
||||
class CStringArray {
|
||||
public:
|
||||
explicit CStringArray(const std::vector<std::string>& strings) noexcept
|
||||
: size_(strings.size()) {
|
||||
if (size_ <= inplace_buffer_.size()) {
|
||||
c_strs_ = inplace_buffer_.data();
|
||||
} else {
|
||||
allocated_buffer_ = std::make_unique<const char*[]>(size_);
|
||||
c_strs_ = allocated_buffer_.get();
|
||||
}
|
||||
for (size_t i = 0; i < size_; ++i) {
|
||||
c_strs_[i] = strings[i].c_str();
|
||||
}
|
||||
}
|
||||
|
||||
CStringArray(const CStringArray&) = delete;
|
||||
CStringArray& operator=(const CStringArray&) = delete;
|
||||
|
||||
const char** c_strs() const { return c_strs_; }
|
||||
size_t size() const { return size_; }
|
||||
|
||||
const char** argv() const { return c_strs_; }
|
||||
int32_t argc() const { return static_cast<int32_t>(size_); }
|
||||
|
||||
private:
|
||||
const char** c_strs_{};
|
||||
size_t size_{};
|
||||
std::array<const char*, kInplaceBufferSize> inplace_buffer_;
|
||||
std::unique_ptr<const char*[]> allocated_buffer_;
|
||||
};
|
||||
|
||||
extern "C" inline node_embedding_status NAPI_CDECL
|
||||
HandleTestError(void* handler_data,
|
||||
|
@ -38,7 +64,7 @@ HandleTestError(void* handler_data,
|
|||
return node_embedding_status_ok;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // __cplusplus
|
||||
|
||||
extern const char* main_script;
|
||||
|
||||
|
@ -50,40 +76,10 @@ void ThrowLastErrorMessage(napi_env env, const char* message);
|
|||
|
||||
std::string FormatString(const char* format, ...);
|
||||
|
||||
template <typename TLambda, typename TFunctor>
|
||||
struct Adapter {
|
||||
static_assert(sizeof(TLambda) == -1, "Unsupported signature");
|
||||
};
|
||||
|
||||
template <typename TLambda, typename TResult, typename... TArgs>
|
||||
struct Adapter<TLambda, TResult(void*, TArgs...)> {
|
||||
static TResult Invoke(void* data, TArgs... args) {
|
||||
return reinterpret_cast<TLambda*>(data)->operator()(args...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TFunctor, typename TLambda>
|
||||
inline TFunctor AsFunctorRef(TLambda&& lambda) {
|
||||
using TLambdaType = std::remove_reference_t<TLambda>;
|
||||
using TAdapter =
|
||||
Adapter<TLambdaType,
|
||||
std::remove_pointer_t<
|
||||
decltype(std::remove_reference_t<TFunctor>::invoke)>>;
|
||||
return TFunctor{static_cast<void*>(&lambda), &TAdapter::Invoke};
|
||||
}
|
||||
|
||||
template <typename TFunctor, typename TLambda>
|
||||
inline TFunctor AsFunctor(TLambda&& lambda) {
|
||||
using TLambdaType = std::remove_reference_t<TLambda>;
|
||||
using TAdapter =
|
||||
Adapter<TLambdaType,
|
||||
std::remove_pointer_t<
|
||||
decltype(std::remove_reference_t<TFunctor>::invoke)>>;
|
||||
return TFunctor{
|
||||
static_cast<void*>(new TLambdaType(std::forward<TLambdaType>(lambda))),
|
||||
&TAdapter::Invoke,
|
||||
[](void* data) { delete static_cast<TLambdaType*>(data); }};
|
||||
}
|
||||
node_embedding_status LoadUtf8Script(
|
||||
node_embedding_runtime_config runtime_config,
|
||||
std::string script,
|
||||
const node_embedding_handle_result_functor& handle_result = {});
|
||||
|
||||
//
|
||||
// Error handling macros copied from test/js_native_api/common.h
|
|
@ -0,0 +1,113 @@
|
|||
#include "embedtest_c_api_common.h"
|
||||
|
||||
using namespace node;
|
||||
|
||||
// Test the no_browser_globals option.
|
||||
extern "C" int32_t test_main_c_api_env_no_browser_globals(int32_t argc,
|
||||
char* argv[]) {
|
||||
return node_embedding_run_main(
|
||||
argc,
|
||||
argv,
|
||||
{},
|
||||
AsFunctorRef<node_embedding_configure_runtime_functor_ref>(
|
||||
[](node_embedding_platform platform,
|
||||
node_embedding_runtime_config runtime_config) {
|
||||
CHECK_STATUS(node_embedding_runtime_set_flags(
|
||||
runtime_config,
|
||||
node_embedding_runtime_flags_no_browser_globals));
|
||||
return LoadUtf8Script(runtime_config,
|
||||
R"JS(
|
||||
const assert = require('assert');
|
||||
const path = require('path');
|
||||
const relativeRequire =
|
||||
require('module').createRequire(path.join(process.cwd(), 'stub.js'));
|
||||
const { intrinsics, nodeGlobals } =
|
||||
relativeRequire('./test/common/globals');
|
||||
const items = Object.getOwnPropertyNames(globalThis);
|
||||
const leaks = [];
|
||||
for (const item of items) {
|
||||
if (intrinsics.has(item)) {
|
||||
continue;
|
||||
}
|
||||
if (nodeGlobals.has(item)) {
|
||||
continue;
|
||||
}
|
||||
if (item === '$jsDebugIsRegistered') {
|
||||
continue;
|
||||
}
|
||||
leaks.push(item);
|
||||
}
|
||||
assert.deepStrictEqual(leaks, []);
|
||||
)JS");
|
||||
}));
|
||||
}
|
||||
|
||||
// Test ESM loaded
|
||||
extern "C" int32_t test_main_c_api_env_with_esm_loader(int32_t argc,
|
||||
char* argv[]) {
|
||||
// We currently cannot pass argument to command line arguments to the runtime.
|
||||
// They must be parsed by the platform.
|
||||
std::vector<std::string> args_vec(argv, argv + argc);
|
||||
args_vec.push_back("--experimental-vm-modules");
|
||||
CStringArray args(args_vec);
|
||||
return node_embedding_run_main(
|
||||
args.argc(),
|
||||
const_cast<char**>(args.argv()),
|
||||
{},
|
||||
AsFunctorRef<node_embedding_configure_runtime_functor_ref>(
|
||||
[](node_embedding_platform platform,
|
||||
node_embedding_runtime_config runtime_config) {
|
||||
return LoadUtf8Script(runtime_config,
|
||||
R"JS(
|
||||
globalThis.require = require('module').createRequire(process.execPath);
|
||||
const { SourceTextModule } = require('node:vm');
|
||||
(async () => {
|
||||
const stmString = 'globalThis.importResult = import("")';
|
||||
const m = new SourceTextModule(stmString, {
|
||||
importModuleDynamically: (async () => {
|
||||
const m = new SourceTextModule('');
|
||||
await m.link(() => 0);
|
||||
await m.evaluate();
|
||||
return m.namespace;
|
||||
}),
|
||||
});
|
||||
await m.link(() => 0);
|
||||
await m.evaluate();
|
||||
delete globalThis.importResult;
|
||||
process.exit(0);
|
||||
})();
|
||||
)JS");
|
||||
}));
|
||||
}
|
||||
|
||||
// Test ESM loaded
|
||||
extern "C" int32_t test_main_c_api_env_with_no_esm_loader(int32_t argc,
|
||||
char* argv[]) {
|
||||
return node_embedding_run_main(
|
||||
argc,
|
||||
argv,
|
||||
{},
|
||||
AsFunctorRef<node_embedding_configure_runtime_functor_ref>(
|
||||
[](node_embedding_platform platform,
|
||||
node_embedding_runtime_config runtime_config) {
|
||||
return LoadUtf8Script(runtime_config,
|
||||
R"JS(
|
||||
globalThis.require = require('module').createRequire(process.execPath);
|
||||
const { SourceTextModule } = require('node:vm');
|
||||
(async () => {
|
||||
const stmString = 'globalThis.importResult = import("")';
|
||||
const m = new SourceTextModule(stmString, {
|
||||
importModuleDynamically: (async () => {
|
||||
const m = new SourceTextModule('');
|
||||
await m.link(() => 0);
|
||||
await m.evaluate();
|
||||
return m.namespace;
|
||||
}),
|
||||
});
|
||||
await m.link(() => 0);
|
||||
await m.evaluate();
|
||||
delete globalThis.importResult;
|
||||
})();
|
||||
)JS");
|
||||
}));
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
#include "embedtest_node_api.h"
|
||||
#include "embedtest_c_api_common.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
using namespace node;
|
||||
|
||||
class GreeterModule {
|
||||
public:
|
||||
explicit GreeterModule(std::atomic<int32_t>* counter_ptr)
|
||||
|
@ -89,7 +91,7 @@ extern "C" int32_t test_main_linked_modules_node_api(int32_t argc,
|
|||
std::atomic<int32_t> greeterModuleInitCallCount{0};
|
||||
std::atomic<int32_t> replicatorModuleInitCallCount{0};
|
||||
|
||||
node_embedding_on_error(HandleTestError, argv[0]);
|
||||
node_embedding_on_error({argv[0], HandleTestError, nullptr});
|
||||
|
||||
CHECK_STATUS_OR_EXIT(node_embedding_run_main(
|
||||
argc,
|
||||
|
@ -124,25 +126,10 @@ extern "C" int32_t test_main_linked_modules_node_api(int32_t argc,
|
|||
ReplicatorModule(&replicatorModuleInitCallCount)),
|
||||
NAPI_VERSION));
|
||||
|
||||
CHECK_STATUS(node_embedding_runtime_on_start_execution(
|
||||
runtime_config,
|
||||
AsFunctor<node_embedding_start_execution_functor>(
|
||||
[](node_embedding_runtime runtime,
|
||||
napi_env env,
|
||||
napi_value process,
|
||||
napi_value require,
|
||||
napi_value run_cjs) -> napi_value {
|
||||
napi_value script, undefined, result;
|
||||
NODE_API_CALL(napi_create_string_utf8(
|
||||
env, main_script, NAPI_AUTO_LENGTH, &script));
|
||||
NODE_API_CALL(napi_get_undefined(env, &undefined));
|
||||
NODE_API_CALL(napi_call_function(
|
||||
env, undefined, run_cjs, 1, &script, &result));
|
||||
return result;
|
||||
})));
|
||||
CHECK_STATUS(LoadUtf8Script(runtime_config, main_script));
|
||||
|
||||
return node_embedding_status_ok;
|
||||
}),
|
||||
{}));
|
||||
})));
|
||||
|
||||
ASSERT_OR_EXIT(greeterModuleInitCallCount ==
|
||||
expectedGreeterModuleInitCallCount);
|
|
@ -1,8 +1,10 @@
|
|||
#include "embedtest_node_api.h"
|
||||
#include "embedtest_c_api_common.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
using namespace node;
|
||||
|
||||
// Tests that the same preload callback is called from the main thread and from
|
||||
// the worker thread.
|
||||
extern "C" int32_t test_main_preload_node_api(int32_t argc, char* argv[]) {
|
||||
|
@ -28,26 +30,11 @@ extern "C" int32_t test_main_preload_node_api(int32_t argc, char* argv[]) {
|
|||
NODE_API_CALL_RETURN_VOID(napi_set_named_property(
|
||||
env, global, "preloadValue", value));
|
||||
})));
|
||||
CHECK_STATUS(node_embedding_runtime_on_start_execution(
|
||||
runtime_config,
|
||||
AsFunctor<node_embedding_start_execution_functor>(
|
||||
[](node_embedding_runtime runtime,
|
||||
napi_env env,
|
||||
napi_value process,
|
||||
napi_value require,
|
||||
napi_value run_cjs) -> napi_value {
|
||||
napi_value script, undefined, result;
|
||||
NODE_API_CALL(napi_create_string_utf8(
|
||||
env, main_script, NAPI_AUTO_LENGTH, &script));
|
||||
NODE_API_CALL(napi_get_undefined(env, &undefined));
|
||||
NODE_API_CALL(napi_call_function(
|
||||
env, undefined, run_cjs, 1, &script, &result));
|
||||
return result;
|
||||
})));
|
||||
|
||||
CHECK_STATUS(LoadUtf8Script(runtime_config, main_script));
|
||||
|
||||
return node_embedding_status_ok;
|
||||
}),
|
||||
{}));
|
||||
})));
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -4,5 +4,5 @@
|
|||
// invoked from the libnode shared library as it would be run from the Node.js
|
||||
// CLI. No embedder customizations are available in this case.
|
||||
extern "C" int32_t test_main_nodejs_main_node_api(int32_t argc, char* argv[]) {
|
||||
return node_embedding_run_main(argc, argv, {}, {}, {});
|
||||
return node_embedding_run_main(argc, argv, {}, {});
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
#include "embedtest_node_api.h"
|
||||
#include "embedtest_c_api_common.h"
|
||||
|
||||
#include <condition_variable>
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
using namespace node;
|
||||
|
||||
// Tests that multiple runtimes can be run at the same time in their own
|
||||
// threads. The test creates 12 threads and 12 runtimes. Each runtime runs in it
|
||||
// own thread.
|
||||
|
@ -35,36 +37,26 @@ extern "C" int32_t test_main_threading_runtime_per_thread_node_api(
|
|||
// process.
|
||||
CHECK_STATUS(node_embedding_runtime_set_flags(
|
||||
runtime_config,
|
||||
node_embedding_runtime_default_flags |
|
||||
node_embedding_runtime_no_create_inspector));
|
||||
CHECK_STATUS(node_embedding_runtime_on_start_execution(
|
||||
node_embedding_runtime_flags_default |
|
||||
node_embedding_runtime_flags_no_create_inspector));
|
||||
CHECK_STATUS(LoadUtf8Script(
|
||||
runtime_config,
|
||||
AsFunctor<node_embedding_start_execution_functor>(
|
||||
[](node_embedding_runtime runtime,
|
||||
napi_env env,
|
||||
napi_value process,
|
||||
napi_value require,
|
||||
napi_value run_cjs) -> napi_value {
|
||||
napi_value script, undefined, result;
|
||||
NODE_API_CALL(napi_create_string_utf8(
|
||||
env, main_script, NAPI_AUTO_LENGTH, &script));
|
||||
NODE_API_CALL(napi_get_undefined(env, &undefined));
|
||||
NODE_API_CALL(napi_call_function(
|
||||
env, undefined, run_cjs, 1, &script, &result));
|
||||
return result;
|
||||
main_script,
|
||||
AsFunctor<node_embedding_handle_result_functor>(
|
||||
[&](node_embedding_runtime runtime,
|
||||
napi_env env,
|
||||
napi_value /*value*/) {
|
||||
napi_value global, my_count;
|
||||
NODE_API_CALL_RETURN_VOID(
|
||||
napi_get_global(env, &global));
|
||||
NODE_API_CALL_RETURN_VOID(napi_get_named_property(
|
||||
env, global, "myCount", &my_count));
|
||||
int32_t count;
|
||||
NODE_API_CALL_RETURN_VOID(
|
||||
napi_get_value_int32(env, my_count, &count));
|
||||
global_count.fetch_add(count);
|
||||
})));
|
||||
return node_embedding_status_ok;
|
||||
}),
|
||||
AsFunctorRef<node_embedding_node_api_functor_ref>(
|
||||
[&](node_embedding_runtime runtime, napi_env env) {
|
||||
napi_value global, my_count;
|
||||
NODE_API_CALL_RETURN_VOID(napi_get_global(env, &global));
|
||||
NODE_API_CALL_RETURN_VOID(napi_get_named_property(
|
||||
env, global, "myCount", &my_count));
|
||||
int32_t count;
|
||||
NODE_API_CALL_RETURN_VOID(
|
||||
napi_get_value_int32(env, my_count, &count));
|
||||
global_count.fetch_add(count);
|
||||
})));
|
||||
return node_embedding_status_ok;
|
||||
}();
|
||||
|
@ -116,25 +108,9 @@ extern "C" int32_t test_main_threading_several_runtimes_per_thread_node_api(
|
|||
// process.
|
||||
CHECK_STATUS(node_embedding_runtime_set_flags(
|
||||
runtime_config,
|
||||
node_embedding_runtime_default_flags |
|
||||
node_embedding_runtime_no_create_inspector));
|
||||
CHECK_STATUS(node_embedding_runtime_on_start_execution(
|
||||
runtime_config,
|
||||
AsFunctor<node_embedding_start_execution_functor>(
|
||||
[](node_embedding_runtime runtime,
|
||||
napi_env env,
|
||||
napi_value process,
|
||||
napi_value require,
|
||||
napi_value run_cjs) -> napi_value {
|
||||
napi_value script, undefined, result;
|
||||
NODE_API_CALL(napi_create_string_utf8(
|
||||
env, main_script, NAPI_AUTO_LENGTH, &script));
|
||||
NODE_API_CALL(napi_get_undefined(env, &undefined));
|
||||
NODE_API_CALL(napi_call_function(
|
||||
env, undefined, run_cjs, 1, &script, &result));
|
||||
return result;
|
||||
})));
|
||||
|
||||
node_embedding_runtime_flags_default |
|
||||
node_embedding_runtime_flags_no_create_inspector));
|
||||
CHECK_STATUS(LoadUtf8Script(runtime_config, main_script));
|
||||
return node_embedding_status_ok;
|
||||
}),
|
||||
&runtime));
|
||||
|
@ -142,7 +118,7 @@ extern "C" int32_t test_main_threading_several_runtimes_per_thread_node_api(
|
|||
|
||||
CHECK_STATUS_OR_EXIT(node_embedding_run_node_api(
|
||||
runtime,
|
||||
AsFunctorRef<node_embedding_node_api_functor_ref>(
|
||||
AsFunctorRef<node_embedding_run_node_api_functor_ref>(
|
||||
[&](node_embedding_runtime runtime, napi_env env) {
|
||||
napi_value undefined, global, func;
|
||||
NODE_API_CALL_RETURN_VOID(napi_get_undefined(env, &undefined));
|
||||
|
@ -163,7 +139,7 @@ extern "C" int32_t test_main_threading_several_runtimes_per_thread_node_api(
|
|||
for (node_embedding_runtime runtime : runtimes) {
|
||||
bool has_more_work = false;
|
||||
CHECK_STATUS_OR_EXIT(node_embedding_run_event_loop(
|
||||
runtime, node_embedding_event_loop_run_nowait, &has_more_work));
|
||||
runtime, node_embedding_event_loop_run_mode_nowait, &has_more_work));
|
||||
more_work |= has_more_work;
|
||||
}
|
||||
} while (more_work);
|
||||
|
@ -171,7 +147,7 @@ extern "C" int32_t test_main_threading_several_runtimes_per_thread_node_api(
|
|||
for (node_embedding_runtime runtime : runtimes) {
|
||||
CHECK_STATUS_OR_EXIT(node_embedding_run_node_api(
|
||||
runtime,
|
||||
AsFunctorRef<node_embedding_node_api_functor_ref>(
|
||||
AsFunctorRef<node_embedding_run_node_api_functor_ref>(
|
||||
[&](node_embedding_runtime runtime, napi_env env) {
|
||||
napi_value global, my_count;
|
||||
NODE_API_CALL_RETURN_VOID(napi_get_global(env, &global));
|
||||
|
@ -225,23 +201,7 @@ extern "C" int32_t test_main_threading_runtime_in_several_threads_node_api(
|
|||
AsFunctorRef<node_embedding_configure_runtime_functor_ref>(
|
||||
[&](node_embedding_platform platform,
|
||||
node_embedding_runtime_config runtime_config) {
|
||||
CHECK_STATUS(node_embedding_runtime_on_start_execution(
|
||||
runtime_config,
|
||||
AsFunctor<node_embedding_start_execution_functor>(
|
||||
[](node_embedding_runtime runtime,
|
||||
napi_env env,
|
||||
napi_value process,
|
||||
napi_value require,
|
||||
napi_value run_cjs) -> napi_value {
|
||||
napi_value script, undefined, result;
|
||||
NODE_API_CALL(napi_create_string_utf8(
|
||||
env, main_script, NAPI_AUTO_LENGTH, &script));
|
||||
NODE_API_CALL(napi_get_undefined(env, &undefined));
|
||||
NODE_API_CALL(napi_call_function(
|
||||
env, undefined, run_cjs, 1, &script, &result));
|
||||
return result;
|
||||
})));
|
||||
|
||||
CHECK_STATUS(LoadUtf8Script(runtime_config, main_script));
|
||||
return node_embedding_status_ok;
|
||||
}),
|
||||
&runtime));
|
||||
|
@ -251,7 +211,7 @@ extern "C" int32_t test_main_threading_runtime_in_several_threads_node_api(
|
|||
std::scoped_lock lock(mutex);
|
||||
node_embedding_status status = node_embedding_run_node_api(
|
||||
runtime,
|
||||
AsFunctorRef<node_embedding_node_api_functor_ref>(
|
||||
AsFunctorRef<node_embedding_run_node_api_functor_ref>(
|
||||
[&](node_embedding_runtime runtime, napi_env env) {
|
||||
napi_value undefined, global, func, my_count;
|
||||
NODE_API_CALL_RETURN_VOID(napi_get_undefined(env, &undefined));
|
||||
|
@ -359,21 +319,25 @@ extern "C" int32_t test_main_threading_runtime_in_ui_thread_node_api(
|
|||
// The callback will be invoked from the runtime's event loop
|
||||
// observer thread. It must schedule the work to the UI thread's
|
||||
// event loop.
|
||||
CHECK_STATUS(node_embedding_on_wake_up_event_loop(
|
||||
CHECK_STATUS(node_embedding_runtime_set_task_runner(
|
||||
runtime_config,
|
||||
AsFunctor<node_embedding_event_loop_functor>(
|
||||
[&ui_queue](node_embedding_runtime runtime) {
|
||||
ui_queue.PostTask([runtime, &ui_queue]() {
|
||||
CHECK_STATUS_OR_EXIT(node_embedding_run_event_loop(
|
||||
runtime,
|
||||
node_embedding_event_loop_run_nowait,
|
||||
nullptr));
|
||||
AsFunctor<node_embedding_post_task_functor>(
|
||||
// We capture the ui_queue by reference here because we
|
||||
// guarantee it to be alive till the end of the test. In
|
||||
// real applications, you should use a safer way to capture
|
||||
// the dispatcher queue.
|
||||
[&ui_queue,
|
||||
&runtime](node_embedding_run_task_functor run_task) {
|
||||
// TODO: figure out the termination scenario.
|
||||
ui_queue.PostTask([run_task, &runtime, &ui_queue]() {
|
||||
AsStdFunction(run_task)();
|
||||
|
||||
// Check myCount and stop the processing when it
|
||||
// reaches 5.
|
||||
CHECK_STATUS_OR_EXIT(node_embedding_run_node_api(
|
||||
runtime,
|
||||
AsFunctorRef<node_embedding_node_api_functor_ref>(
|
||||
AsFunctorRef<
|
||||
node_embedding_run_node_api_functor_ref>(
|
||||
[&](node_embedding_runtime runtime,
|
||||
napi_env env) {
|
||||
napi_value global, my_count;
|
||||
|
@ -400,22 +364,7 @@ extern "C" int32_t test_main_threading_runtime_in_ui_thread_node_api(
|
|||
});
|
||||
})));
|
||||
|
||||
CHECK_STATUS(node_embedding_runtime_on_start_execution(
|
||||
runtime_config,
|
||||
AsFunctor<node_embedding_start_execution_functor>(
|
||||
[](node_embedding_runtime runtime,
|
||||
napi_env env,
|
||||
napi_value process,
|
||||
napi_value require,
|
||||
napi_value run_cjs) -> napi_value {
|
||||
napi_value script, undefined, result;
|
||||
NODE_API_CALL(napi_create_string_utf8(
|
||||
env, main_script, NAPI_AUTO_LENGTH, &script));
|
||||
NODE_API_CALL(napi_get_undefined(env, &undefined));
|
||||
NODE_API_CALL(napi_call_function(
|
||||
env, undefined, run_cjs, 1, &script, &result));
|
||||
return result;
|
||||
})));
|
||||
CHECK_STATUS(LoadUtf8Script(runtime_config, main_script));
|
||||
|
||||
return node_embedding_status_ok;
|
||||
}),
|
||||
|
@ -426,7 +375,7 @@ extern "C" int32_t test_main_threading_runtime_in_ui_thread_node_api(
|
|||
ui_queue.PostTask([runtime]() {
|
||||
node_embedding_status status = node_embedding_run_node_api(
|
||||
runtime,
|
||||
AsFunctorRef<node_embedding_node_api_functor_ref>(
|
||||
AsFunctorRef<node_embedding_run_node_api_functor_ref>(
|
||||
[&](node_embedding_runtime runtime, napi_env env) {
|
||||
napi_value undefined, global, func;
|
||||
NODE_API_CALL_RETURN_VOID(napi_get_undefined(env, &undefined));
|
||||
|
@ -441,7 +390,7 @@ extern "C" int32_t test_main_threading_runtime_in_ui_thread_node_api(
|
|||
env, undefined, func, 0, nullptr, nullptr));
|
||||
|
||||
node_embedding_run_event_loop(
|
||||
runtime, node_embedding_event_loop_run_nowait, nullptr);
|
||||
runtime, node_embedding_event_loop_run_mode_nowait, nullptr);
|
||||
}));
|
||||
CHECK_STATUS_OR_EXIT(status);
|
||||
});
|
|
@ -6,12 +6,23 @@ extern "C" int32_t test_main_nodejs_main_node_api(int32_t argc, char* argv[]);
|
|||
extern "C" int32_t test_main_modules_node_api(int32_t argc, char* argv[]);
|
||||
extern "C" int32_t test_main_linked_modules_node_api(int32_t argc,
|
||||
char* argv[]);
|
||||
extern "C" int32_t test_main_threading_runtime_per_thread_node_api(int32_t argc, char* argv[]);
|
||||
extern "C" int32_t test_main_threading_several_runtimes_per_thread_node_api(int32_t argc, char* argv[]);
|
||||
extern "C" int32_t test_main_threading_runtime_in_several_threads_node_api(int32_t argc, char* argv[]);
|
||||
extern "C" int32_t test_main_threading_runtime_in_ui_thread_node_api(int32_t argc, char* argv[]);
|
||||
extern "C" int32_t test_main_threading_runtime_per_thread_node_api(
|
||||
int32_t argc, char* argv[]);
|
||||
extern "C" int32_t test_main_threading_several_runtimes_per_thread_node_api(
|
||||
int32_t argc, char* argv[]);
|
||||
extern "C" int32_t test_main_threading_runtime_in_several_threads_node_api(
|
||||
int32_t argc, char* argv[]);
|
||||
extern "C" int32_t test_main_threading_runtime_in_ui_thread_node_api(
|
||||
int32_t argc, char* argv[]);
|
||||
extern "C" int32_t test_main_preload_node_api(int32_t argc, char* argv[]);
|
||||
|
||||
extern "C" int32_t test_main_c_api_env_no_browser_globals(int32_t argc,
|
||||
char* argv[]);
|
||||
extern "C" int32_t test_main_c_api_env_with_esm_loader(int32_t argc,
|
||||
char* argv[]);
|
||||
extern "C" int32_t test_main_c_api_env_with_no_esm_loader(int32_t argc,
|
||||
char* argv[]);
|
||||
|
||||
typedef int32_t (*main_callback)(int32_t argc, char* argv[]);
|
||||
|
||||
int32_t CallWithoutArg1(main_callback main, int32_t argc, char** argv) {
|
||||
|
@ -39,15 +50,29 @@ NODE_MAIN(int32_t argc, node::argv_type raw_argv[]) {
|
|||
} else if (strcmp(arg1, "linked-modules-node-api") == 0) {
|
||||
return CallWithoutArg1(test_main_linked_modules_node_api, argc, argv);
|
||||
} else if (strcmp(arg1, "threading-runtime-per-thread-node-api") == 0) {
|
||||
return CallWithoutArg1(test_main_threading_runtime_per_thread_node_api, argc, argv);
|
||||
} else if (strcmp(arg1, "threading-several-runtimes-per-thread-node-api") == 0) {
|
||||
return CallWithoutArg1(test_main_threading_several_runtimes_per_thread_node_api, argc, argv);
|
||||
} else if (strcmp(arg1, "threading-runtime-in-several-threads-node-api") == 0) {
|
||||
return CallWithoutArg1(test_main_threading_runtime_in_several_threads_node_api, argc, argv);
|
||||
return CallWithoutArg1(
|
||||
test_main_threading_runtime_per_thread_node_api, argc, argv);
|
||||
} else if (strcmp(arg1, "threading-several-runtimes-per-thread-node-api") ==
|
||||
0) {
|
||||
return CallWithoutArg1(
|
||||
test_main_threading_several_runtimes_per_thread_node_api, argc, argv);
|
||||
} else if (strcmp(arg1, "threading-runtime-in-several-threads-node-api") ==
|
||||
0) {
|
||||
return CallWithoutArg1(
|
||||
test_main_threading_runtime_in_several_threads_node_api, argc, argv);
|
||||
} else if (strcmp(arg1, "threading-runtime-in-ui-thread-node-api") == 0) {
|
||||
return CallWithoutArg1(test_main_threading_runtime_in_ui_thread_node_api, argc, argv);
|
||||
return CallWithoutArg1(
|
||||
test_main_threading_runtime_in_ui_thread_node_api, argc, argv);
|
||||
} else if (strcmp(arg1, "preload-node-api") == 0) {
|
||||
return CallWithoutArg1(test_main_preload_node_api, argc, argv);
|
||||
} else if (strcmp(arg1, "c-api-env-no-browser-globals") == 0) {
|
||||
return CallWithoutArg1(
|
||||
test_main_c_api_env_no_browser_globals, argc, argv);
|
||||
} else if (strcmp(arg1, "c-api-env-with-esm-loader") == 0) {
|
||||
return CallWithoutArg1(test_main_c_api_env_with_esm_loader, argc, argv);
|
||||
} else if (strcmp(arg1, "c-api-env-with-no-esm-loader") == 0) {
|
||||
return CallWithoutArg1(
|
||||
test_main_c_api_env_with_no_esm_loader, argc, argv);
|
||||
}
|
||||
}
|
||||
return test_main_cpp_api(argc, argv);
|
||||
|
|
|
@ -383,6 +383,34 @@ runSnapshotTests('cpp-api');
|
|||
);
|
||||
}
|
||||
|
||||
function runEnvTests(apiType) {
|
||||
runTest(
|
||||
`${apiType}: Env No Browser Globals`,
|
||||
spawnSyncAndExitWithoutError,
|
||||
[`${apiType}-env-no-browser-globals`],
|
||||
{}
|
||||
);
|
||||
|
||||
runTest(
|
||||
`${apiType}: Env With ESM Loader`,
|
||||
spawnSyncAndExitWithoutError,
|
||||
[`${apiType}-env-with-esm-loader`],
|
||||
{}
|
||||
);
|
||||
|
||||
runTest(
|
||||
`${apiType}: Env With No ESM Loader`,
|
||||
spawnSyncAndExit,
|
||||
[`${apiType}-env-with-no-esm-loader`],
|
||||
{
|
||||
status: 1,
|
||||
signal: null,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
runEnvTests('c-api');
|
||||
|
||||
/*
|
||||
runTest(
|
||||
`modules-node-api: load modules`,
|
||||
|
|
Loading…
Reference in New Issue