src: use RAII to manage the main isolate data · nodejs/node@cab1dc5 (original) (raw)
`@@ -25,16 +25,12 @@
`
25
25
``
26
26
`#include "debug_utils.h"
`
27
27
`#include "node_binding.h"
`
28
``
`-
#include "node_buffer.h"
`
29
``
`-
#include "node_constants.h"
`
30
``
`-
#include "node_context_data.h"
`
31
``
`-
#include "node_errors.h"
`
32
28
`#include "node_internals.h"
`
``
29
`+
#include "node_main_instance.h"
`
33
30
`#include "node_metadata.h"
`
34
31
`#include "node_native_module_env.h"
`
35
32
`#include "node_options-inl.h"
`
36
33
`#include "node_perf.h"
`
37
``
`-
#include "node_platform.h"
`
38
34
`#include "node_process.h"
`
39
35
`#include "node_revert.h"
`
40
36
`#include "node_v8_platform-inl.h"
`
`@@ -56,13 +52,6 @@
`
56
52
`#include "node_dtrace.h"
`
57
53
`#endif
`
58
54
``
59
``
`-
#include "async_wrap-inl.h"
`
60
``
`-
#include "env-inl.h"
`
61
``
`-
#include "handle_wrap.h"
`
62
``
`-
#include "req_wrap-inl.h"
`
63
``
`-
#include "string_bytes.h"
`
64
``
`-
#include "util.h"
`
65
``
`-
#include "uv.h"
`
66
55
`#if NODE_USE_V8_PLATFORM
`
67
56
`#include "libplatform/libplatform.h"
`
68
57
`#endif // NODE_USE_V8_PLATFORM
`
`@@ -122,23 +111,19 @@ using native_module::NativeModuleEnv;
`
122
111
`using options_parser::kAllowedInEnvironment;
`
123
112
`using options_parser::kDisallowedInEnvironment;
`
124
113
``
125
``
`-
using v8::Array;
`
126
114
`using v8::Boolean;
`
127
115
`using v8::Context;
`
128
``
`-
using v8::DEFAULT;
`
129
116
`using v8::EscapableHandleScope;
`
130
117
`using v8::Exception;
`
131
118
`using v8::Function;
`
132
119
`using v8::FunctionCallbackInfo;
`
133
120
`using v8::HandleScope;
`
134
121
`using v8::Isolate;
`
135
122
`using v8::Local;
`
136
``
`-
using v8::Locker;
`
137
123
`using v8::Maybe;
`
138
124
`using v8::MaybeLocal;
`
139
125
`using v8::Object;
`
140
126
`using v8::Script;
`
141
``
`-
using v8::SealHandleScope;
`
142
127
`using v8::String;
`
143
128
`using v8::Undefined;
`
144
129
`using v8::V8;
`
`@@ -767,161 +752,6 @@ void Init(int* argc,
`
767
752
` argv[i] = strdup(argv_[i].c_str());
`
768
753
`}
`
769
754
``
770
``
`-
void RunBeforeExit(Environment* env) {
`
771
``
`-
env->RunBeforeExitCallbacks();
`
772
``
-
773
``
`-
if (!uv_loop_alive(env->event_loop()))
`
774
``
`-
EmitBeforeExit(env);
`
775
``
`-
}
`
776
``
-
777
``
`-
// TODO(joyeecheung): align this with the CreateEnvironment exposed in node.h
`
778
``
`-
// and the environment creation routine in workers somehow.
`
779
``
`-
inline std::unique_ptr CreateMainEnvironment(
`
780
``
`-
IsolateData* isolate_data,
`
781
``
`-
const std::vectorstd::string& args,
`
782
``
`-
const std::vectorstd::string& exec_args,
`
783
``
`-
int* exit_code) {
`
784
``
`-
Isolate* isolate = isolate_data->isolate();
`
785
``
`-
HandleScope handle_scope(isolate);
`
786
``
-
787
``
`-
// TODO(addaleax): This should load a real per-Isolate option, currently
`
788
``
`-
// this is still effectively per-process.
`
789
``
`-
if (isolate_data->options()->track_heap_objects) {
`
790
``
`-
isolate->GetHeapProfiler()->StartTrackingHeapObjects(true);
`
791
``
`-
}
`
792
``
-
793
``
`-
Local context = NewContext(isolate);
`
794
``
`-
Context::Scope context_scope(context);
`
795
``
-
796
``
`-
std::unique_ptr env = std::make_unique(
`
797
``
`-
isolate_data,
`
798
``
`-
context,
`
799
``
`-
static_castEnvironment::Flags(Environment::kIsMainThread |
`
800
``
`-
Environment::kOwnsProcessState |
`
801
``
`-
Environment::kOwnsInspector));
`
802
``
`-
env->InitializeLibuv(per_process::v8_is_profiling);
`
803
``
`-
env->ProcessCliArgs(args, exec_args);
`
804
``
-
805
``
`-
#if HAVE_INSPECTOR && NODE_USE_V8_PLATFORM
`
806
``
`-
CHECK(!env->inspector_agent()->IsListening());
`
807
``
`-
// Inspector agent can't fail to start, but if it was configured to listen
`
808
``
`-
// right away on the websocket port and fails to bind/etc, this will return
`
809
``
`-
// false.
`
810
``
`-
env->inspector_agent()->Start(args.size() > 1 ? args[1].c_str() : "",
`
811
``
`-
env->options()->debug_options(),
`
812
``
`-
env->inspector_host_port(),
`
813
``
`-
true);
`
814
``
`-
if (env->options()->debug_options().inspector_enabled &&
`
815
``
`-
!env->inspector_agent()->IsListening()) {
`
816
``
`-
*exit_code = 12; // Signal internal error.
`
817
``
`-
return env;
`
818
``
`-
}
`
819
``
`-
#else
`
820
``
`-
// inspector_enabled can't be true if !HAVE_INSPECTOR or !NODE_USE_V8_PLATFORM
`
821
``
`-
// - the option parser should not allow that.
`
822
``
`-
CHECK(!env->options()->debug_options().inspector_enabled);
`
823
``
`-
#endif // HAVE_INSPECTOR && NODE_USE_V8_PLATFORM
`
824
``
-
825
``
`-
if (RunBootstrapping(env.get()).IsEmpty()) {
`
826
``
`-
*exit_code = 1;
`
827
``
`-
}
`
828
``
-
829
``
`-
return env;
`
830
``
`-
}
`
831
``
-
832
``
`-
inline int StartNodeWithIsolate(Isolate* isolate,
`
833
``
`-
IsolateData* isolate_data,
`
834
``
`-
const std::vectorstd::string& args,
`
835
``
`-
const std::vectorstd::string& exec_args) {
`
836
``
`-
int exit_code = 0;
`
837
``
`-
std::unique_ptr env =
`
838
``
`-
CreateMainEnvironment(isolate_data, args, exec_args, &exit_code);
`
839
``
`-
CHECK_NOT_NULL(env);
`
840
``
`-
HandleScope handle_scope(env->isolate());
`
841
``
`-
Context::Scope context_scope(env->context());
`
842
``
-
843
``
`-
if (exit_code == 0) {
`
844
``
`-
{
`
845
``
`-
AsyncCallbackScope callback_scope(env.get());
`
846
``
`-
env->async_hooks()->push_async_ids(1, 0);
`
847
``
`-
LoadEnvironment(env.get());
`
848
``
`-
env->async_hooks()->pop_async_id(1);
`
849
``
`-
}
`
850
``
-
851
``
`-
{
`
852
``
`-
SealHandleScope seal(isolate);
`
853
``
`-
bool more;
`
854
``
`-
env->performance_state()->Mark(
`
855
``
`-
node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_START);
`
856
``
`-
do {
`
857
``
`-
uv_run(env->event_loop(), UV_RUN_DEFAULT);
`
858
``
-
859
``
`-
per_process::v8_platform.DrainVMTasks(isolate);
`
860
``
-
861
``
`-
more = uv_loop_alive(env->event_loop());
`
862
``
`-
if (more && !env->is_stopping()) continue;
`
863
``
-
864
``
`-
RunBeforeExit(env.get());
`
865
``
-
866
``
`` -
// Emit beforeExit
if the loop became alive either after emitting
``
867
``
`-
// event, or after running some callbacks.
`
868
``
`-
more = uv_loop_alive(env->event_loop());
`
869
``
`-
} while (more == true && !env->is_stopping());
`
870
``
`-
env->performance_state()->Mark(
`
871
``
`-
node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_EXIT);
`
872
``
`-
}
`
873
``
-
874
``
`-
env->set_trace_sync_io(false);
`
875
``
`-
exit_code = EmitExit(env.get());
`
876
``
`-
WaitForInspectorDisconnect(env.get());
`
877
``
`-
}
`
878
``
-
879
``
`-
env->set_can_call_into_js(false);
`
880
``
`-
env->stop_sub_worker_contexts();
`
881
``
`-
uv_tty_reset_mode();
`
882
``
`-
env->RunCleanup();
`
883
``
`-
RunAtExit(env.get());
`
884
``
-
885
``
`-
per_process::v8_platform.DrainVMTasks(isolate);
`
886
``
`-
per_process::v8_platform.CancelVMTasks(isolate);
`
887
``
-
888
``
`-
#if defined(LEAK_SANITIZER)
`
889
``
`-
__lsan_do_leak_check();
`
890
``
`-
#endif
`
891
``
-
892
``
`-
return exit_code;
`
893
``
`-
}
`
894
``
-
895
``
`-
inline int StartNodeWithLoopAndArgs(uv_loop_t* event_loop,
`
896
``
`-
const std::vectorstd::string& args,
`
897
``
`-
const std::vectorstd::string& exec_args) {
`
898
``
`-
std::unique_ptr<ArrayBufferAllocator, decltype(&FreeArrayBufferAllocator)>
`
899
``
`-
allocator(CreateArrayBufferAllocator(), &FreeArrayBufferAllocator);
`
900
``
`-
Isolate* const isolate = NewIsolate(allocator.get(), event_loop);
`
901
``
`-
if (isolate == nullptr)
`
902
``
`-
return 12; // Signal internal error.
`
903
``
-
904
``
`-
int exit_code;
`
905
``
`-
{
`
906
``
`-
Locker locker(isolate);
`
907
``
`-
Isolate::Scope isolate_scope(isolate);
`
908
``
`-
HandleScope handle_scope(isolate);
`
909
``
`-
std::unique_ptr<IsolateData, decltype(&FreeIsolateData)> isolate_data(
`
910
``
`-
CreateIsolateData(isolate,
`
911
``
`-
event_loop,
`
912
``
`-
per_process::v8_platform.Platform(),
`
913
``
`-
allocator.get()),
`
914
``
`-
&FreeIsolateData);
`
915
``
`-
exit_code =
`
916
``
`-
StartNodeWithIsolate(isolate, isolate_data.get(), args, exec_args);
`
917
``
`-
}
`
918
``
-
919
``
`-
isolate->Dispose();
`
920
``
`-
per_process::v8_platform.Platform()->UnregisterIsolate(isolate);
`
921
``
-
922
``
`-
return exit_code;
`
923
``
`-
}
`
924
``
-
925
755
`int Start(int argc, char** argv) {
`
926
756
`atexit([] () { uv_tty_reset_mode(); });
`
927
757
`PlatformInit();
`
`@@ -981,8 +811,13 @@ int Start(int argc, char** argv) {
`
981
811
`V8::Initialize();
`
982
812
` performance::performance_v8_start = PERFORMANCE_NOW();
`
983
813
` per_process::v8_initialized = true;
`
984
``
`-
const int exit_code =
`
985
``
`-
StartNodeWithLoopAndArgs(uv_default_loop(), args, exec_args);
`
``
814
+
``
815
`+
int exit_code = 0;
`
``
816
`+
{
`
``
817
`+
NodeMainInstance main_instance(uv_default_loop(), args, exec_args);
`
``
818
`+
exit_code = main_instance.Run();
`
``
819
`+
}
`
``
820
+
986
821
` per_process::v8_initialized = false;
`
987
822
`V8::Dispose();
`
988
823
``