1 // Copyright (c) 2015 GitHub, Inc.
2 // Use of this source code is governed by the MIT license that can be
3 // found in the LICENSE file.
5 #include "atom/app/node_main.h"
7 #include "atom/app/uv_task_runner.h"
8 #include "atom/browser/javascript_environment.h"
9 #include "atom/browser/node_debugger.h"
10 #include "atom/common/api/atom_bindings.h"
11 #include "atom/common/crash_reporter/crash_reporter.h"
12 #include "atom/common/native_mate_converters/string16_converter.h"
13 #include "base/command_line.h"
14 #include "base/feature_list.h"
15 #include "base/threading/thread_task_runner_handle.h"
16 #include "gin/array_buffer.h"
17 #include "gin/public/isolate_holder.h"
18 #include "gin/v8_initializer.h"
19 #include "native_mate/dictionary.h"
21 #include "atom/common/node_includes.h"
25 int NodeMain(int argc, char *argv[]) {
26 base::CommandLine::Init(argc, argv);
30 // Feed gin::PerIsolateData with a task runner.
31 argv = uv_setup_args(argc, argv);
32 uv_loop_t* loop = uv_default_loop();
33 scoped_refptr<UvTaskRunner> uv_task_runner(new UvTaskRunner(loop));
34 base::ThreadTaskRunnerHandle handle(uv_task_runner);
36 // Initialize feature list.
37 std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
38 feature_list->InitializeFromCommandLine("", "");
39 base::FeatureList::SetInstance(std::move(feature_list));
41 gin::V8Initializer::LoadV8Snapshot();
42 gin::V8Initializer::LoadV8Natives();
43 JavascriptEnvironment gin_env;
46 const char** exec_argv;
47 // node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv); not called
49 node::IsolateData isolate_data(gin_env.isolate(), loop);
50 node::Environment* env = node::CreateEnvironment(
51 &isolate_data, gin_env.context(), argc, argv,
52 exec_argc, exec_argv);
54 // Start our custom debugger implementation.
55 // NodeDebugger node_debugger(gin_env.isolate()); not called
56 // if (node_debugger.IsRunning())
57 // env->AssignToContext(v8::Debug::GetDebugContext(gin_env.isolate()));
59 mate::Dictionary process(gin_env.isolate(), env->process_object());
61 process.SetMethod("log", &AtomBindings::Log);
63 process.SetMethod("crash", &AtomBindings::Crash);
65 // Setup process.crashReporter.start in child node processes
66 auto reporter = mate::Dictionary::CreateEmpty(gin_env.isolate());
67 reporter.SetMethod("start", &crash_reporter::CrashReporter::StartInstance);
68 process.Set("crashReporter", reporter);
70 node::LoadEnvironment(env);
74 more = uv_run(env->event_loop(), UV_RUN_ONCE);
76 node::EmitBeforeExit(env);
78 // Emit `beforeExit` if the loop became alive either after emitting
79 // event, or after running some callbacks.
80 more = uv_loop_alive(env->event_loop());
81 if (uv_run(env->event_loop(), UV_RUN_NOWAIT) != 0)
84 } while (more == true);
86 exit_code = node::EmitExit(env);
89 node::FreeEnvironment(env);