mirror of
https://github.com/nodejs/node.git
synced 2026-10-28 18:25:13 +08:00
The term "native module" dates back to some of the oldest code in the code base. Within the context of Node.js core it usually refers to modules that are native to Node.js (e.g. fs, http), but it can cause confusion for people who don't work on this part of the code base, as "native module" can also refer to native addons - which is even the case in some of the API docs and error messages. This patch tries to make the usage of these terms more consistent. Now within the context of Node.js core: - JavaScript scripts that are built-in to Node.js are now referred to as "built-in(s)". If they are available as modules, they can also be referred to as "built-in module(s)". - Dynamically-linked shared objects that are loaded into the Node.js processes are referred to as "addons". We will try to avoid using the term "native modules" because it could be ambiguous. Changes in this patch: File names: - node_native_module.h -> node_builtins.h, - node_native_module.cc -> node_builtins.cc C++ binding names: - `native_module` -> `builtins` `node::Environment`: - `native_modules_without_cache` -> `builtins_without_cache` - `native_modules_with_cache` -> `builtins_with_cache` - `native_modules_in_snapshot` -> `builtins_in_cache` - `native_module_require` -> `builtin_module_require` `node::EnvSerializeInfo`: - `native_modules` -> `builtins `node::native_module::NativeModuleLoader`: - `native_module` namespace -> `builtins` namespace - `NativeModuleLoader` -> `BuiltinLoader` - `NativeModuleRecordMap` -> `BuiltinSourceMap` - `NativeModuleCacheMap` -> `BuiltinCodeCacheMap` - `ModuleIds` -> `BuiltinIds` - `ModuleCategories` -> `BuiltinCategories` - `LoadBuiltinModuleSource` -> `LoadBuiltinSource` `loader.js`: - `NativeModule` -> `BuiltinModule` (the `NativeModule` name used in `process.moduleLoadList` is kept for compatibility) And other clarifications in the documentation and comments. PR-URL: https://github.com/nodejs/node/pull/44135 Fixes: https://github.com/nodejs/node/issues/44036 Reviewed-By: Jacob Smith <jacob@frende.me> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Michael Dawson <midawson@redhat.com> Reviewed-By: Richard Lau <rlau@redhat.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Jan Krems <jan.krems@gmail.com>
212 lines
6.6 KiB
C++
212 lines
6.6 KiB
C++
#include "node_main_instance.h"
|
|
#include <memory>
|
|
#if HAVE_OPENSSL
|
|
#include "crypto/crypto_util.h"
|
|
#endif // HAVE_OPENSSL
|
|
#include "debug_utils-inl.h"
|
|
#include "node_builtins.h"
|
|
#include "node_external_reference.h"
|
|
#include "node_internals.h"
|
|
#include "node_options-inl.h"
|
|
#include "node_snapshot_builder.h"
|
|
#include "node_snapshotable.h"
|
|
#include "node_v8_platform-inl.h"
|
|
#include "util-inl.h"
|
|
#if defined(LEAK_SANITIZER)
|
|
#include <sanitizer/lsan_interface.h>
|
|
#endif
|
|
|
|
#if HAVE_INSPECTOR
|
|
#include "inspector/worker_inspector.h" // ParentInspectorHandle
|
|
#endif
|
|
|
|
namespace node {
|
|
|
|
using v8::Context;
|
|
using v8::HandleScope;
|
|
using v8::Isolate;
|
|
using v8::Local;
|
|
using v8::Locker;
|
|
|
|
NodeMainInstance::NodeMainInstance(Isolate* isolate,
|
|
uv_loop_t* event_loop,
|
|
MultiIsolatePlatform* platform,
|
|
const std::vector<std::string>& args,
|
|
const std::vector<std::string>& exec_args)
|
|
: args_(args),
|
|
exec_args_(exec_args),
|
|
array_buffer_allocator_(nullptr),
|
|
isolate_(isolate),
|
|
platform_(platform),
|
|
isolate_data_(nullptr),
|
|
snapshot_data_(nullptr) {
|
|
isolate_data_ =
|
|
std::make_unique<IsolateData>(isolate_, event_loop, platform, nullptr);
|
|
|
|
SetIsolateMiscHandlers(isolate_, {});
|
|
}
|
|
|
|
std::unique_ptr<NodeMainInstance> NodeMainInstance::Create(
|
|
Isolate* isolate,
|
|
uv_loop_t* event_loop,
|
|
MultiIsolatePlatform* platform,
|
|
const std::vector<std::string>& args,
|
|
const std::vector<std::string>& exec_args) {
|
|
return std::unique_ptr<NodeMainInstance>(
|
|
new NodeMainInstance(isolate, event_loop, platform, args, exec_args));
|
|
}
|
|
|
|
NodeMainInstance::NodeMainInstance(const SnapshotData* snapshot_data,
|
|
uv_loop_t* event_loop,
|
|
MultiIsolatePlatform* platform,
|
|
const std::vector<std::string>& args,
|
|
const std::vector<std::string>& exec_args)
|
|
: args_(args),
|
|
exec_args_(exec_args),
|
|
array_buffer_allocator_(ArrayBufferAllocator::Create()),
|
|
isolate_(nullptr),
|
|
platform_(platform),
|
|
isolate_data_(),
|
|
isolate_params_(std::make_unique<Isolate::CreateParams>()),
|
|
snapshot_data_(snapshot_data) {
|
|
isolate_params_->array_buffer_allocator = array_buffer_allocator_.get();
|
|
if (snapshot_data != nullptr) {
|
|
SnapshotBuilder::InitializeIsolateParams(snapshot_data,
|
|
isolate_params_.get());
|
|
}
|
|
|
|
isolate_ = Isolate::Allocate();
|
|
CHECK_NOT_NULL(isolate_);
|
|
// Register the isolate on the platform before the isolate gets initialized,
|
|
// so that the isolate can access the platform during initialization.
|
|
platform->RegisterIsolate(isolate_, event_loop);
|
|
SetIsolateCreateParamsForNode(isolate_params_.get());
|
|
Isolate::Initialize(isolate_, *isolate_params_);
|
|
|
|
// If the indexes are not nullptr, we are not deserializing
|
|
isolate_data_ = std::make_unique<IsolateData>(
|
|
isolate_,
|
|
event_loop,
|
|
platform,
|
|
array_buffer_allocator_.get(),
|
|
snapshot_data == nullptr ? nullptr : &(snapshot_data->isolate_data_info));
|
|
IsolateSettings s;
|
|
SetIsolateMiscHandlers(isolate_, s);
|
|
if (snapshot_data == nullptr) {
|
|
// If in deserialize mode, delay until after the deserialization is
|
|
// complete.
|
|
SetIsolateErrorHandlers(isolate_, s);
|
|
}
|
|
isolate_data_->max_young_gen_size =
|
|
isolate_params_->constraints.max_young_generation_size_in_bytes();
|
|
}
|
|
|
|
void NodeMainInstance::Dispose() {
|
|
// This should only be called on a main instance that does not own its
|
|
// isolate.
|
|
CHECK_NULL(isolate_params_);
|
|
platform_->DrainTasks(isolate_);
|
|
}
|
|
|
|
NodeMainInstance::~NodeMainInstance() {
|
|
if (isolate_params_ == nullptr) {
|
|
return;
|
|
}
|
|
// This should only be done on a main instance that owns its isolate.
|
|
platform_->UnregisterIsolate(isolate_);
|
|
isolate_->Dispose();
|
|
}
|
|
|
|
int NodeMainInstance::Run() {
|
|
Locker locker(isolate_);
|
|
Isolate::Scope isolate_scope(isolate_);
|
|
HandleScope handle_scope(isolate_);
|
|
|
|
int exit_code = 0;
|
|
DeleteFnPtr<Environment, FreeEnvironment> env =
|
|
CreateMainEnvironment(&exit_code);
|
|
CHECK_NOT_NULL(env);
|
|
|
|
Context::Scope context_scope(env->context());
|
|
Run(&exit_code, env.get());
|
|
return exit_code;
|
|
}
|
|
|
|
void NodeMainInstance::Run(int* exit_code, Environment* env) {
|
|
if (*exit_code == 0) {
|
|
LoadEnvironment(env, StartExecutionCallback{});
|
|
|
|
*exit_code = SpinEventLoop(env).FromMaybe(1);
|
|
}
|
|
|
|
#if defined(LEAK_SANITIZER)
|
|
__lsan_do_leak_check();
|
|
#endif
|
|
}
|
|
|
|
DeleteFnPtr<Environment, FreeEnvironment>
|
|
NodeMainInstance::CreateMainEnvironment(int* exit_code) {
|
|
*exit_code = 0; // Reset the exit code to 0
|
|
|
|
HandleScope handle_scope(isolate_);
|
|
|
|
// TODO(addaleax): This should load a real per-Isolate option, currently
|
|
// this is still effectively per-process.
|
|
if (isolate_data_->options()->track_heap_objects) {
|
|
isolate_->GetHeapProfiler()->StartTrackingHeapObjects(true);
|
|
}
|
|
|
|
Local<Context> context;
|
|
DeleteFnPtr<Environment, FreeEnvironment> env;
|
|
|
|
if (snapshot_data_ != nullptr) {
|
|
env.reset(new Environment(isolate_data_.get(),
|
|
isolate_,
|
|
args_,
|
|
exec_args_,
|
|
&(snapshot_data_->env_info),
|
|
EnvironmentFlags::kDefaultFlags,
|
|
{}));
|
|
context = Context::FromSnapshot(isolate_,
|
|
SnapshotData::kNodeMainContextIndex,
|
|
{DeserializeNodeInternalFields, env.get()})
|
|
.ToLocalChecked();
|
|
|
|
CHECK(!context.IsEmpty());
|
|
Context::Scope context_scope(context);
|
|
|
|
CHECK(InitializeContextRuntime(context).IsJust());
|
|
SetIsolateErrorHandlers(isolate_, {});
|
|
env->InitializeMainContext(context, &(snapshot_data_->env_info));
|
|
#if HAVE_INSPECTOR
|
|
env->InitializeInspector({});
|
|
#endif
|
|
env->DoneBootstrapping();
|
|
|
|
#if HAVE_OPENSSL
|
|
crypto::InitCryptoOnce(isolate_);
|
|
#endif // HAVE_OPENSSL
|
|
} else {
|
|
context = NewContext(isolate_);
|
|
CHECK(!context.IsEmpty());
|
|
Context::Scope context_scope(context);
|
|
env.reset(new Environment(isolate_data_.get(),
|
|
context,
|
|
args_,
|
|
exec_args_,
|
|
nullptr,
|
|
EnvironmentFlags::kDefaultFlags,
|
|
{}));
|
|
#if HAVE_INSPECTOR
|
|
env->InitializeInspector({});
|
|
#endif
|
|
if (env->RunBootstrapping().IsEmpty()) {
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
return env;
|
|
}
|
|
|
|
} // namespace node
|