2019-04-18 10:26:48 +02:00
|
|
|
#include <cstdio>
|
|
|
|
#include <iostream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "libplatform/libplatform.h"
|
|
|
|
#include "node_internals.h"
|
2022-04-11 18:38:57 +02:00
|
|
|
#include "node_snapshot_builder.h"
|
2019-05-17 22:36:05 +02:00
|
|
|
#include "util-inl.h"
|
2019-04-18 10:26:48 +02:00
|
|
|
#include "v8.h"
|
|
|
|
|
2022-03-24 14:37:08 +01:00
|
|
|
int BuildSnapshot(int argc, char* argv[]);
|
|
|
|
|
2019-04-18 10:26:48 +02:00
|
|
|
#ifdef _WIN32
|
|
|
|
#include <windows.h>
|
|
|
|
|
2022-03-24 14:37:08 +01:00
|
|
|
int wmain(int argc, wchar_t* wargv[]) {
|
|
|
|
// Windows needs conversion from wchar_t to char.
|
|
|
|
|
|
|
|
// Convert argv to UTF8.
|
|
|
|
char** argv = new char*[argc + 1];
|
|
|
|
for (int i = 0; i < argc; i++) {
|
|
|
|
// Compute the size of the required buffer
|
|
|
|
DWORD size = WideCharToMultiByte(
|
|
|
|
CP_UTF8, 0, wargv[i], -1, nullptr, 0, nullptr, nullptr);
|
|
|
|
if (size == 0) {
|
|
|
|
// This should never happen.
|
|
|
|
fprintf(stderr, "Could not convert arguments to utf8.");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
// Do the actual conversion
|
|
|
|
argv[i] = new char[size];
|
|
|
|
DWORD result = WideCharToMultiByte(
|
|
|
|
CP_UTF8, 0, wargv[i], -1, argv[i], size, nullptr, nullptr);
|
|
|
|
if (result == 0) {
|
|
|
|
// This should never happen.
|
|
|
|
fprintf(stderr, "Could not convert arguments to utf8.");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
argv[argc] = nullptr;
|
2019-04-18 10:26:48 +02:00
|
|
|
#else // UNIX
|
|
|
|
int main(int argc, char* argv[]) {
|
2020-10-04 02:04:49 +02:00
|
|
|
argv = uv_setup_args(argc, argv);
|
2022-03-24 14:37:08 +01:00
|
|
|
|
|
|
|
// Disable stdio buffering, it interacts poorly with printf()
|
|
|
|
// calls elsewhere in the program (e.g., any logging from V8.)
|
|
|
|
setvbuf(stdout, nullptr, _IONBF, 0);
|
|
|
|
setvbuf(stderr, nullptr, _IONBF, 0);
|
2019-04-18 10:26:48 +02:00
|
|
|
#endif // _WIN32
|
|
|
|
|
2022-03-24 14:37:08 +01:00
|
|
|
return BuildSnapshot(argc, argv);
|
|
|
|
}
|
2019-08-15 14:39:26 +02:00
|
|
|
|
2022-03-24 14:37:08 +01:00
|
|
|
int BuildSnapshot(int argc, char* argv[]) {
|
2019-04-18 10:26:48 +02:00
|
|
|
if (argc < 2) {
|
|
|
|
std::cerr << "Usage: " << argv[0] << " <path/to/output.cc>\n";
|
2022-03-24 14:37:08 +01:00
|
|
|
std::cerr << " " << argv[0] << " --build-snapshot "
|
|
|
|
<< "<path/to/script.js> <path/to/output.cc>\n";
|
2019-04-18 10:26:48 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2024-05-02 21:54:02 +02:00
|
|
|
std::shared_ptr<node::InitializationResult> result =
|
src: add detailed embedder process initialization API
So far, process initialization has been a bit all over the place
in Node.js. `InitializeNodeWithArgs()` is our main public API
for this, but inclusion of items in it vs. `InitializeOncePerProcess()`
and `PlatformInit()` has been random at best. Likewise,
some pieces of initialization have been guarded by
`NODE_SHARED_MODE`, but also fairly randomly and without
any meaningful connection to shared library usage.
This leaves embedders in a position to cherry-pick some of
the initialization code into their own code to make their
application behave like typical Node.js applications to the
degree to which they desire it.
Electron takes an alternative route and makes direct use of
`InitializeOncePerProcess()` already while it is a private
API, with a `TODO` to add it to the public API in Node.js.
This commit addresses that `TODO`, and `TODO`s around the
`NODE_SHARED_MODE` usage. Specifically:
- `InitializeOncePerProcess()` and `TearDownOncePerProcess()`
are added to the public API.
- The `flags` option of these functions are merged with the
`flags` option for `InitializeNodeWithArgs()`, since they
essentially share the same semantics.
- The return value of the function is made an abstract class,
rather than a struct, for easier API/ABI stability.
- Initialization code from `main()` is brought into these
functions (since that makes sense in general).
- Add a `TODO` for turning `InitializeNodeWithArgs()` into
a small wrapper around `InitializeOncePerProcess()` and
eventually removing it (at least one major release cycle
each, presumably).
- Remove `NODE_SHARED_MODE` guards and replace them with
runtime options.
PR-URL: https://github.com/nodejs/node/pull/44121
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
2022-08-05 21:46:08 +02:00
|
|
|
node::InitializeOncePerProcess(
|
2023-10-09 04:53:19 +02:00
|
|
|
std::vector<std::string>(argv, argv + argc),
|
|
|
|
node::ProcessInitializationFlags::kGeneratePredictableSnapshot);
|
2020-04-30 10:03:59 +02:00
|
|
|
|
src: add detailed embedder process initialization API
So far, process initialization has been a bit all over the place
in Node.js. `InitializeNodeWithArgs()` is our main public API
for this, but inclusion of items in it vs. `InitializeOncePerProcess()`
and `PlatformInit()` has been random at best. Likewise,
some pieces of initialization have been guarded by
`NODE_SHARED_MODE`, but also fairly randomly and without
any meaningful connection to shared library usage.
This leaves embedders in a position to cherry-pick some of
the initialization code into their own code to make their
application behave like typical Node.js applications to the
degree to which they desire it.
Electron takes an alternative route and makes direct use of
`InitializeOncePerProcess()` already while it is a private
API, with a `TODO` to add it to the public API in Node.js.
This commit addresses that `TODO`, and `TODO`s around the
`NODE_SHARED_MODE` usage. Specifically:
- `InitializeOncePerProcess()` and `TearDownOncePerProcess()`
are added to the public API.
- The `flags` option of these functions are merged with the
`flags` option for `InitializeNodeWithArgs()`, since they
essentially share the same semantics.
- The return value of the function is made an abstract class,
rather than a struct, for easier API/ABI stability.
- Initialization code from `main()` is brought into these
functions (since that makes sense in general).
- Add a `TODO` for turning `InitializeNodeWithArgs()` into
a small wrapper around `InitializeOncePerProcess()` and
eventually removing it (at least one major release cycle
each, presumably).
- Remove `NODE_SHARED_MODE` guards and replace them with
runtime options.
PR-URL: https://github.com/nodejs/node/pull/44121
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
2022-08-05 21:46:08 +02:00
|
|
|
CHECK(!result->early_return());
|
|
|
|
CHECK_EQ(result->exit_code(), 0);
|
2019-04-18 10:26:48 +02:00
|
|
|
|
2022-03-24 14:37:08 +01:00
|
|
|
std::string out_path;
|
2023-10-28 19:05:59 +02:00
|
|
|
std::optional<std::string_view> builder_script_path = std::nullopt;
|
2023-01-24 21:35:27 +01:00
|
|
|
if (node::per_process::cli_options->per_isolate->build_snapshot) {
|
2023-10-28 19:05:59 +02:00
|
|
|
builder_script_path = result->args()[1];
|
src: add detailed embedder process initialization API
So far, process initialization has been a bit all over the place
in Node.js. `InitializeNodeWithArgs()` is our main public API
for this, but inclusion of items in it vs. `InitializeOncePerProcess()`
and `PlatformInit()` has been random at best. Likewise,
some pieces of initialization have been guarded by
`NODE_SHARED_MODE`, but also fairly randomly and without
any meaningful connection to shared library usage.
This leaves embedders in a position to cherry-pick some of
the initialization code into their own code to make their
application behave like typical Node.js applications to the
degree to which they desire it.
Electron takes an alternative route and makes direct use of
`InitializeOncePerProcess()` already while it is a private
API, with a `TODO` to add it to the public API in Node.js.
This commit addresses that `TODO`, and `TODO`s around the
`NODE_SHARED_MODE` usage. Specifically:
- `InitializeOncePerProcess()` and `TearDownOncePerProcess()`
are added to the public API.
- The `flags` option of these functions are merged with the
`flags` option for `InitializeNodeWithArgs()`, since they
essentially share the same semantics.
- The return value of the function is made an abstract class,
rather than a struct, for easier API/ABI stability.
- Initialization code from `main()` is brought into these
functions (since that makes sense in general).
- Add a `TODO` for turning `InitializeNodeWithArgs()` into
a small wrapper around `InitializeOncePerProcess()` and
eventually removing it (at least one major release cycle
each, presumably).
- Remove `NODE_SHARED_MODE` guards and replace them with
runtime options.
PR-URL: https://github.com/nodejs/node/pull/44121
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
2022-08-05 21:46:08 +02:00
|
|
|
out_path = result->args()[2];
|
2022-03-24 14:37:08 +01:00
|
|
|
} else {
|
src: add detailed embedder process initialization API
So far, process initialization has been a bit all over the place
in Node.js. `InitializeNodeWithArgs()` is our main public API
for this, but inclusion of items in it vs. `InitializeOncePerProcess()`
and `PlatformInit()` has been random at best. Likewise,
some pieces of initialization have been guarded by
`NODE_SHARED_MODE`, but also fairly randomly and without
any meaningful connection to shared library usage.
This leaves embedders in a position to cherry-pick some of
the initialization code into their own code to make their
application behave like typical Node.js applications to the
degree to which they desire it.
Electron takes an alternative route and makes direct use of
`InitializeOncePerProcess()` already while it is a private
API, with a `TODO` to add it to the public API in Node.js.
This commit addresses that `TODO`, and `TODO`s around the
`NODE_SHARED_MODE` usage. Specifically:
- `InitializeOncePerProcess()` and `TearDownOncePerProcess()`
are added to the public API.
- The `flags` option of these functions are merged with the
`flags` option for `InitializeNodeWithArgs()`, since they
essentially share the same semantics.
- The return value of the function is made an abstract class,
rather than a struct, for easier API/ABI stability.
- Initialization code from `main()` is brought into these
functions (since that makes sense in general).
- Add a `TODO` for turning `InitializeNodeWithArgs()` into
a small wrapper around `InitializeOncePerProcess()` and
eventually removing it (at least one major release cycle
each, presumably).
- Remove `NODE_SHARED_MODE` guards and replace them with
runtime options.
PR-URL: https://github.com/nodejs/node/pull/44121
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
2022-08-05 21:46:08 +02:00
|
|
|
out_path = result->args()[1];
|
2022-03-24 14:37:08 +01:00
|
|
|
}
|
|
|
|
|
2023-08-24 18:02:26 +02:00
|
|
|
#ifdef NODE_MKSNAPSHOT_USE_ARRAY_LITERALS
|
|
|
|
bool use_array_literals = true;
|
2023-08-14 14:53:02 +02:00
|
|
|
#else
|
2023-08-24 18:02:26 +02:00
|
|
|
bool use_array_literals = false;
|
2023-08-14 14:53:02 +02:00
|
|
|
#endif
|
2022-03-24 14:37:08 +01:00
|
|
|
|
2023-10-28 19:05:59 +02:00
|
|
|
node::SnapshotConfig snapshot_config;
|
|
|
|
snapshot_config.builder_script_path = builder_script_path;
|
|
|
|
|
|
|
|
#ifdef NODE_USE_NODE_CODE_CACHE
|
|
|
|
snapshot_config.flags = node::SnapshotFlags::kDefault;
|
|
|
|
#else
|
|
|
|
snapshot_config.flags = node::SnapshotFlags::kWithoutCodeCache;
|
|
|
|
#endif
|
|
|
|
|
2023-08-14 14:53:02 +02:00
|
|
|
node::ExitCode exit_code =
|
|
|
|
node::SnapshotBuilder::GenerateAsSource(out_path.c_str(),
|
|
|
|
result->args(),
|
|
|
|
result->exec_args(),
|
2023-10-28 19:05:59 +02:00
|
|
|
snapshot_config,
|
2023-08-24 18:02:26 +02:00
|
|
|
use_array_literals);
|
2019-04-18 10:26:48 +02:00
|
|
|
|
|
|
|
node::TearDownOncePerProcess();
|
2022-10-06 14:41:16 +02:00
|
|
|
return static_cast<int>(exit_code);
|
2019-04-18 10:26:48 +02:00
|
|
|
}
|