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

``