1 #include "node.h"
2 #include "uv.h"
3 #include <assert.h>
4 
5 #include <algorithm>
6 
7 // Note: This file is being referred to from doc/api/embedding.md, and excerpts
8 // from it are included in the documentation. Try to keep these in sync.
9 
10 using node::CommonEnvironmentSetup;
11 using node::Environment;
12 using node::MultiIsolatePlatform;
13 using v8::Context;
14 using v8::HandleScope;
15 using v8::Isolate;
16 using v8::Locker;
17 using v8::MaybeLocal;
18 using v8::V8;
19 using v8::Value;
20 
21 static int RunNodeInstance(MultiIsolatePlatform* platform,
22                            const std::vector<std::string>& args,
23                            const std::vector<std::string>& exec_args);
24 
main(int argc, char** argv)25 int main(int argc, char** argv) {
26   argv = uv_setup_args(argc, argv);
27   std::vector<std::string> args(argv, argv + argc);
28   std::unique_ptr<node::InitializationResult> result =
29       node::InitializeOncePerProcess(
30           args,
31           {node::ProcessInitializationFlags::kNoInitializeV8,
32            node::ProcessInitializationFlags::kNoInitializeNodeV8Platform});
33 
34   for (const std::string& error : result->errors())
35     fprintf(stderr, "%s: %s\n", args[0].c_str(), error.c_str());
36   if (result->early_return() != 0) {
37     return result->exit_code();
38   }
39 
40   std::unique_ptr<MultiIsolatePlatform> platform =
41       MultiIsolatePlatform::Create(4);
42   V8::InitializePlatform(platform.get());
43   V8::Initialize();
44 
45   int ret =
46       RunNodeInstance(platform.get(), result->args(), result->exec_args());
47 
48   V8::Dispose();
49   V8::DisposePlatform();
50 
51   node::TearDownOncePerProcess();
52   return ret;
53 }
54 
RunNodeInstance(MultiIsolatePlatform* platform, const std::vector<std::string>& args, const std::vector<std::string>& exec_args)55 int RunNodeInstance(MultiIsolatePlatform* platform,
56                     const std::vector<std::string>& args,
57                     const std::vector<std::string>& exec_args) {
58   int exit_code = 0;
59 
60   std::vector<std::string> errors;
61   std::unique_ptr<CommonEnvironmentSetup> setup =
62       CommonEnvironmentSetup::Create(platform, &errors, args, exec_args);
63   if (!setup) {
64     for (const std::string& err : errors)
65       fprintf(stderr, "%s: %s\n", args[0].c_str(), err.c_str());
66     return 1;
67   }
68 
69   Isolate* isolate = setup->isolate();
70   Environment* env = setup->env();
71 
72   {
73     Locker locker(isolate);
74     Isolate::Scope isolate_scope(isolate);
75     HandleScope handle_scope(isolate);
76     Context::Scope context_scope(setup->context());
77 
78     MaybeLocal<Value> loadenv_ret = node::LoadEnvironment(
79         env,
80         "const publicRequire ="
81         "  require('module').createRequire(process.cwd() + '/');"
82         "globalThis.require = publicRequire;"
83         "globalThis.embedVars = { nön_ascıı: '�️‍�' };"
84         "require('vm').runInThisContext(process.argv[1]);");
85 
86     if (loadenv_ret.IsEmpty())  // There has been a JS exception.
87       return 1;
88 
89     exit_code = node::SpinEventLoop(env).FromMaybe(1);
90 
91     node::Stop(env);
92   }
93 
94   return exit_code;
95 }
96