diff --git a/src/node.cc b/src/node.cc index 6411eafb8cb61f..495b5d7d6363cc 100644 --- a/src/node.cc +++ b/src/node.cc @@ -4425,10 +4425,21 @@ int EmitExit(Environment* env) { } +ArrayBufferAllocator* CreateArrayBufferAllocator() { + return new ArrayBufferAllocator(); +} + + +void FreeArrayBufferAllocator(ArrayBufferAllocator* allocator) { + delete allocator; +} + + IsolateData* CreateIsolateData(Isolate* isolate, uv_loop_t* loop) { return new IsolateData(isolate, loop, nullptr); } + IsolateData* CreateIsolateData( Isolate* isolate, uv_loop_t* loop, @@ -4437,6 +4448,15 @@ IsolateData* CreateIsolateData( } +IsolateData* CreateIsolateData( + Isolate* isolate, + uv_loop_t* loop, + MultiIsolatePlatform* platform, + ArrayBufferAllocator* allocator) { + return new IsolateData(isolate, loop, platform, allocator->zero_fill_field()); +} + + void FreeIsolateData(IsolateData* isolate_data) { delete isolate_data; } @@ -4580,19 +4600,16 @@ bool AllowWasmCodeGenerationCallback( return wasm_code_gen->IsUndefined() || wasm_code_gen->IsTrue(); } -inline int Start(uv_loop_t* event_loop, - int argc, const char* const* argv, - int exec_argc, const char* const* exec_argv) { +Isolate* NewIsolate(ArrayBufferAllocator* allocator) { Isolate::CreateParams params; - ArrayBufferAllocator allocator; - params.array_buffer_allocator = &allocator; + params.array_buffer_allocator = allocator; #ifdef NODE_ENABLE_VTUNE_PROFILING params.code_event_handler = vTune::GetVtuneCodeEventHandler(); #endif - Isolate* const isolate = Isolate::New(params); + Isolate* isolate = Isolate::New(params); if (isolate == nullptr) - return 12; // Signal internal error. + return nullptr; isolate->AddMessageListener(OnMessage); isolate->SetAbortOnUncaughtExceptionCallback(ShouldAbortOnUncaughtException); @@ -4600,6 +4617,18 @@ inline int Start(uv_loop_t* event_loop, isolate->SetFatalErrorHandler(OnFatalError); isolate->SetAllowWasmCodeGenerationCallback(AllowWasmCodeGenerationCallback); + return isolate; +} + +inline int Start(uv_loop_t* event_loop, + int argc, const char* const* argv, + int exec_argc, const char* const* exec_argv) { + std::unique_ptr + allocator(CreateArrayBufferAllocator(), &FreeArrayBufferAllocator); + Isolate* const isolate = NewIsolate(allocator.get()); + if (isolate == nullptr) + return 12; // Signal internal error. + { Mutex::ScopedLock scoped_lock(node_isolate_mutex); CHECK_EQ(node_isolate, nullptr); @@ -4611,15 +4640,18 @@ inline int Start(uv_loop_t* event_loop, Locker locker(isolate); Isolate::Scope isolate_scope(isolate); HandleScope handle_scope(isolate); - IsolateData isolate_data( - isolate, - event_loop, - v8_platform.Platform(), - allocator.zero_fill_field()); + std::unique_ptr isolate_data( + CreateIsolateData( + isolate, + event_loop, + v8_platform.Platform(), + allocator.get()), + &FreeIsolateData); if (track_heap_objects) { isolate->GetHeapProfiler()->StartTrackingHeapObjects(true); } - exit_code = Start(isolate, &isolate_data, argc, argv, exec_argc, exec_argv); + exit_code = + Start(isolate, isolate_data.get(), argc, argv, exec_argc, exec_argv); } { diff --git a/src/node.h b/src/node.h index 23e2e9995ce209..ce742926f165c9 100644 --- a/src/node.h +++ b/src/node.h @@ -214,6 +214,11 @@ NODE_EXTERN void Init(int* argc, int* exec_argc, const char*** exec_argv); +class ArrayBufferAllocator; + +NODE_EXTERN ArrayBufferAllocator* CreateArrayBufferAllocator(); +NODE_EXTERN void FreeArrayBufferAllocator(ArrayBufferAllocator* allocator); + class IsolateData; class Environment; @@ -229,9 +234,21 @@ class MultiIsolatePlatform : public v8::Platform { virtual void UnregisterIsolate(IsolateData* isolate_data) = 0; }; +// Creates a new isolate with Node.js-specific settings. +NODE_EXTERN v8::Isolate* NewIsolate(ArrayBufferAllocator* allocator); + +// Creates a new context with Node.js-specific tweaks. Currently, it removes +// the `v8BreakIterator` property from the global `Intl` object if present. +// See https://github.com/nodejs/node/issues/14909 for more info. +NODE_EXTERN v8::Local NewContext( + v8::Isolate* isolate, + v8::Local object_template = + v8::Local()); + // If `platform` is passed, it will be used to register new Worker instances. // It can be `nullptr`, in which case creating new Workers inside of // Environments that use this `IsolateData` will not work. +// TODO(helloshuangzi): switch to default parameters. NODE_EXTERN IsolateData* CreateIsolateData( v8::Isolate* isolate, struct uv_loop_s* loop); @@ -239,6 +256,11 @@ NODE_EXTERN IsolateData* CreateIsolateData( v8::Isolate* isolate, struct uv_loop_s* loop, MultiIsolatePlatform* platform); +NODE_EXTERN IsolateData* CreateIsolateData( + v8::Isolate* isolate, + struct uv_loop_s* loop, + MultiIsolatePlatform* platform, + ArrayBufferAllocator* allocator); NODE_EXTERN void FreeIsolateData(IsolateData* isolate_data); NODE_EXTERN Environment* CreateEnvironment(IsolateData* isolate_data, diff --git a/src/node_internals.h b/src/node_internals.h index 8aa46318803985..edd5f6f6e59cab 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -227,14 +227,6 @@ inline v8::Local PersistentToLocal( v8::Isolate* isolate, const Persistent& persistent); -// Creates a new context with Node.js-specific tweaks. Currently, it removes -// the `v8BreakIterator` property from the global `Intl` object if present. -// See https://github.com/nodejs/node/issues/14909 for more info. -v8::Local NewContext( - v8::Isolate* isolate, - v8::Local object_template = - v8::Local()); - // Convert a struct sockaddr to a { address: '1.2.3.4', port: 1234 } JS object. // Sets address and port properties on the info object and returns it. // If |info| is omitted, a new object is returned.