Skip to content

Commit cfe1924

Browse files
authored
Merge pull request #2 from alshdavid-forks/vmoroz-alshdavid-node_embedding_api
Vmoroz alshdavid node embedding api
2 parents 3256e39 + 21bb93d commit cfe1924

File tree

8 files changed

+321
-145
lines changed

8 files changed

+321
-145
lines changed

doc/api/embedding.md

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -167,47 +167,46 @@ int RunNodeInstance(MultiIsolatePlatform* platform,
167167
}
168168
```
169169

170-
# C embedder API
170+
## C runtime API
171171

172172
<!--introduced_in=REPLACEME-->
173173

174174
While Node.js provides an extensive C++ embedding API that can be used from C++
175175
applications, the C-based API is useful when Node.js is embedded as a shared
176176
libnode library into C++ or non-C++ applications.
177177

178-
## API design overview
178+
### API design overview
179179

180-
One of the goals for the C based embedder API is to be ABI stable. It means that
180+
One of the goals for the C based runtime API is to be ABI stable. It means that
181181
applications must be able to use newer libnode versions without recompilation.
182182
The following design principles are targeting to achieve that goal.
183183

184-
- Follow the best practices for the [node-api][] design and build on top of
184+
* Follow the best practices for the [node-api][] design and build on top of
185185
the [node-api][].
186186

187-
## API reference
187+
### API reference
188188

189189
#### Functions
190190

191-
##### `node_embedding_main`
191+
##### `node_rt_main`
192192

193193
<!-- YAML
194194
added: REPLACEME
195195
-->
196196

197197
> Stability: 1 - Experimental
198198
199-
Runs Node.js runtime instance.
199+
Runs Node.js runtime instance the same way as the Node.js executable.
200200

201201
```c
202-
int32_t NAPI_CDECL node_embedding_main(
202+
int32_t NAPI_CDECL node_rt_main(
203203
int32_t argc,
204204
char* argv[]);
205205
```
206206
207-
- `[in] argc`: Number of items in the `argv` array.
208-
- `[in] argv`: CLI arguments as an array of zero terminated strings.
209-
210-
Returns `int32_t` with instance exit code.
207+
* `[in] argc`: Number of items in the `argv` array.
208+
* `[in] argv`: CLI arguments as an array of zero terminated strings.
209+
Returns `int32_t` with runtime instance exit code.
211210
212211
[CLI options]: cli.md
213212
[`process.memoryUsage()`]: process.md#processmemoryusage

node.gyp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@
138138
'src/node_report.cc',
139139
'src/node_report_module.cc',
140140
'src/node_report_utils.cc',
141+
'src/node_runtime_api.cc',
141142
'src/node_sea.cc',
142143
'src/node_serdes.cc',
143144
'src/node_shadow_realm.cc',
@@ -247,6 +248,7 @@
247248
'src/module_wrap.h',
248249
'src/node.h',
249250
'src/node_api.h',
251+
'src/node_api_internals.h',
250252
'src/node_api_types.h',
251253
'src/node_binding.h',
252254
'src/node_blob.h',
@@ -291,6 +293,7 @@
291293
'src/node_report.h',
292294
'src/node_revert.h',
293295
'src/node_root_certs.h',
296+
'src/node_runtime_api.h',
294297
'src/node_sea.h',
295298
'src/node_shadow_realm.h',
296299
'src/node_snapshotable.h',
@@ -1315,6 +1318,8 @@
13151318
'sources': [
13161319
'src/node_snapshot_stub.cc',
13171320
'test/embedding/embedtest.cc',
1321+
'test/embedding/embedtest_c_api_main.c',
1322+
'test/embedding/embedtest_main.cc',
13181323
],
13191324

13201325
'conditions': [

src/node_runtime_api.cc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//
2+
// Description: C-based API for embedding Node.js.
3+
//
4+
// !!! WARNING !!! WARNING !!! WARNING !!!
5+
// This is a new API and is subject to change.
6+
// While it is C-based, it is not ABI safe yet.
7+
// Consider all functions and data structures as experimental.
8+
// !!! WARNING !!! WARNING !!! WARNING !!!
9+
//
10+
// This file contains the C-based API for embedding Node.js in a host
11+
// application. The API is designed to be used by applications that want to
12+
// embed Node.js as a shared library (.so or .dll) and can interop with
13+
// C-based API.
14+
//
15+
16+
#include "node_runtime_api.h"
17+
#include "node.h"
18+
19+
EXTERN_C_START
20+
21+
int32_t NAPI_CDECL node_rt_main(int32_t argc, char* argv[]) {
22+
return node::Start(argc, argv);
23+
}
24+
25+
EXTERN_C_END

src/node_runtime_api.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//
2+
// Description: C-based API for embedding Node.js.
3+
//
4+
// !!! WARNING !!! WARNING !!! WARNING !!!
5+
// This is a new API and is subject to change.
6+
// While it is C-based, it is not ABI safe yet.
7+
// Consider all functions and data structures as experimental.
8+
// !!! WARNING !!! WARNING !!! WARNING !!!
9+
//
10+
// This file contains the C-based API for embedding Node.js in a host
11+
// application. The API is designed to be used by applications that want to
12+
// embed Node.js as a shared library (.so or .dll) and can interop with
13+
// C-based API.
14+
//
15+
16+
#ifndef SRC_NODE_RUNTIME_API_H_
17+
#define SRC_NODE_RUNTIME_API_H_
18+
19+
#include "node_api.h"
20+
21+
EXTERN_C_START
22+
23+
// Runs Node.js main function. It is the same as running Node.js from CLI.
24+
NAPI_EXTERN int32_t NAPI_CDECL node_rt_main(int32_t argc, char* argv[]);
25+
26+
EXTERN_C_END
27+
28+
#endif // SRC_NODE_RUNTIME_API_H_

test/embedding/embedtest.cc

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
#endif
44
#include <assert.h>
55
#include "cppgc/platform.h"
6-
#include "executable_wrapper.h"
76
#include "node.h"
7+
#include "uv.h"
88

99
#include <algorithm>
1010

@@ -28,10 +28,7 @@ static int RunNodeInstance(MultiIsolatePlatform* platform,
2828
const std::vector<std::string>& args,
2929
const std::vector<std::string>& exec_args);
3030

31-
NODE_MAIN(int argc, node::argv_type raw_argv[]) {
32-
char** argv = nullptr;
33-
node::FixupMain(argc, raw_argv, &argv);
34-
31+
int32_t test_main_cpp_api(int32_t argc, char* argv[]) {
3532
std::vector<std::string> args(argv, argv + argc);
3633
std::shared_ptr<node::InitializationResult> result =
3734
node::InitializeOncePerProcess(
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include "node_runtime_api.h"
2+
3+
// The simplest Node.js embedding scenario where the Node.js main function is
4+
// invoked from the libnode shared library as it would be run from the Node.js
5+
// CLI.
6+
int32_t test_main_c_api_nodejs_main(int32_t argc, char* argv[]) {
7+
return node_rt_main(argc, argv);
8+
}

test/embedding/embedtest_main.cc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include <cstring>
2+
#include <string_view>
3+
#include <unordered_map>
4+
#include "executable_wrapper.h"
5+
6+
int32_t test_main_cpp_api(int32_t argc, char* argv[]);
7+
8+
extern "C" int32_t test_main_c_api_nodejs_main(int32_t argc, char* argv[]);
9+
10+
using MainCallback = int32_t (*)(int32_t argc, char* argv[]);
11+
12+
int32_t CallWithoutArg1(MainCallback main, int32_t argc, char* argv[]) {
13+
for (int32_t i = 2; i < argc; i++) {
14+
argv[i - 1] = argv[i];
15+
}
16+
argv[--argc] = nullptr;
17+
return main(argc, argv);
18+
}
19+
20+
NODE_MAIN(int32_t argc, node::argv_type raw_argv[]) {
21+
char** argv = nullptr;
22+
node::FixupMain(argc, raw_argv, &argv);
23+
24+
const std::unordered_map<std::string_view, MainCallback> main_map = {
25+
{"cpp-api", test_main_cpp_api},
26+
{"c-api-nodejs-main", test_main_c_api_nodejs_main},
27+
};
28+
if (argc > 1) {
29+
char* arg1 = argv[1];
30+
for (const auto& [key, value] : main_map) {
31+
if (key == arg1) {
32+
return CallWithoutArg1(value, argc, argv);
33+
}
34+
}
35+
}
36+
return test_main_cpp_api(argc, argv);
37+
}

0 commit comments

Comments
 (0)