mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
src: move C++ binding/addon related code into node_binding{.h, .cc}
This patch: - Moves the C++ binding/addon related code out of node_internals.h/node.cc and into dedicated files node_binding.h/node_binding.cc, and only puts the code resued by other files into the header. - Introduce a node::binding namespace so that code exposed to other files can be easily recognized. PR-URL: https://github.com/nodejs/node/pull/24701 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Richard Lau <riclau@uk.ibm.com>
This commit is contained in:
2
node.gyp
2
node.gyp
@@ -343,6 +343,7 @@
|
||||
'src/module_wrap.cc',
|
||||
'src/node.cc',
|
||||
'src/node_api.cc',
|
||||
'src/node_binding.cc',
|
||||
'src/node_buffer.cc',
|
||||
'src/node_config.cc',
|
||||
'src/node_constants.cc',
|
||||
@@ -414,6 +415,7 @@
|
||||
'src/node.h',
|
||||
'src/node_api.h',
|
||||
'src/node_api_types.h',
|
||||
'src/node_binding.h',
|
||||
'src/node_buffer.h',
|
||||
'src/node_constants.h',
|
||||
'src/node_context_data.h',
|
||||
|
||||
409
src/node.cc
409
src/node.cc
@@ -19,6 +19,7 @@
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#include "node_binding.h"
|
||||
#include "node_buffer.h"
|
||||
#include "node_constants.h"
|
||||
#include "node_context_data.h"
|
||||
@@ -113,20 +114,6 @@ typedef int mode_t;
|
||||
#include <grp.h> // getgrnam()
|
||||
#endif
|
||||
|
||||
#if defined(__POSIX__)
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
// This is used to load built-in modules. Instead of using
|
||||
// __attribute__((constructor)), we call the _register_<modname>
|
||||
// function for each built-in modules explicitly in
|
||||
// node::RegisterBuiltinModules(). This is only forward declaration.
|
||||
// The definitions are in each module's implementation when calling
|
||||
// the NODE_BUILTIN_MODULE_CONTEXT_AWARE.
|
||||
#define V(modname) void _register_##modname();
|
||||
NODE_BUILTIN_MODULES(V)
|
||||
#undef V
|
||||
|
||||
namespace node {
|
||||
|
||||
using native_module::NativeModuleLoader;
|
||||
@@ -173,13 +160,6 @@ using v8::V8;
|
||||
using v8::Value;
|
||||
|
||||
static bool v8_is_profiling = false;
|
||||
static bool node_is_initialized = false;
|
||||
static uv_once_t init_modpending_once = UV_ONCE_INIT;
|
||||
static uv_key_t thread_local_modpending;
|
||||
static node_module* modlist_builtin;
|
||||
static node_module* modlist_internal;
|
||||
static node_module* modlist_linked;
|
||||
static node_module* modlist_addon;
|
||||
|
||||
#ifdef NODE_EXPERIMENTAL_HTTP
|
||||
static const char llhttp_version[] =
|
||||
@@ -825,257 +805,6 @@ static void Exit(const FunctionCallbackInfo<Value>& args) {
|
||||
env->Exit(code);
|
||||
}
|
||||
|
||||
extern "C" void node_module_register(void* m) {
|
||||
struct node_module* mp = reinterpret_cast<struct node_module*>(m);
|
||||
|
||||
if (mp->nm_flags & NM_F_BUILTIN) {
|
||||
mp->nm_link = modlist_builtin;
|
||||
modlist_builtin = mp;
|
||||
} else if (mp->nm_flags & NM_F_INTERNAL) {
|
||||
mp->nm_link = modlist_internal;
|
||||
modlist_internal = mp;
|
||||
} else if (!node_is_initialized) {
|
||||
// "Linked" modules are included as part of the node project.
|
||||
// Like builtins they are registered *before* node::Init runs.
|
||||
mp->nm_flags = NM_F_LINKED;
|
||||
mp->nm_link = modlist_linked;
|
||||
modlist_linked = mp;
|
||||
} else {
|
||||
uv_key_set(&thread_local_modpending, mp);
|
||||
}
|
||||
}
|
||||
|
||||
inline struct node_module* FindModule(struct node_module* list,
|
||||
const char* name,
|
||||
int flag) {
|
||||
struct node_module* mp;
|
||||
|
||||
for (mp = list; mp != nullptr; mp = mp->nm_link) {
|
||||
if (strcmp(mp->nm_modname, name) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
CHECK(mp == nullptr || (mp->nm_flags & flag) != 0);
|
||||
return mp;
|
||||
}
|
||||
|
||||
node_module* get_builtin_module(const char* name) {
|
||||
return FindModule(modlist_builtin, name, NM_F_BUILTIN);
|
||||
}
|
||||
node_module* get_internal_module(const char* name) {
|
||||
return FindModule(modlist_internal, name, NM_F_INTERNAL);
|
||||
}
|
||||
node_module* get_linked_module(const char* name) {
|
||||
return FindModule(modlist_linked, name, NM_F_LINKED);
|
||||
}
|
||||
|
||||
class DLib {
|
||||
public:
|
||||
#ifdef __POSIX__
|
||||
static const int kDefaultFlags = RTLD_LAZY;
|
||||
#else
|
||||
static const int kDefaultFlags = 0;
|
||||
#endif
|
||||
|
||||
inline DLib(const char* filename, int flags)
|
||||
: filename_(filename), flags_(flags), handle_(nullptr) {}
|
||||
|
||||
inline bool Open();
|
||||
inline void Close();
|
||||
inline void* GetSymbolAddress(const char* name);
|
||||
|
||||
const std::string filename_;
|
||||
const int flags_;
|
||||
std::string errmsg_;
|
||||
void* handle_;
|
||||
#ifndef __POSIX__
|
||||
uv_lib_t lib_;
|
||||
#endif
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(DLib);
|
||||
};
|
||||
|
||||
|
||||
#ifdef __POSIX__
|
||||
bool DLib::Open() {
|
||||
handle_ = dlopen(filename_.c_str(), flags_);
|
||||
if (handle_ != nullptr)
|
||||
return true;
|
||||
errmsg_ = dlerror();
|
||||
return false;
|
||||
}
|
||||
|
||||
void DLib::Close() {
|
||||
if (handle_ == nullptr) return;
|
||||
dlclose(handle_);
|
||||
handle_ = nullptr;
|
||||
}
|
||||
|
||||
void* DLib::GetSymbolAddress(const char* name) {
|
||||
return dlsym(handle_, name);
|
||||
}
|
||||
#else // !__POSIX__
|
||||
bool DLib::Open() {
|
||||
int ret = uv_dlopen(filename_.c_str(), &lib_);
|
||||
if (ret == 0) {
|
||||
handle_ = static_cast<void*>(lib_.handle);
|
||||
return true;
|
||||
}
|
||||
errmsg_ = uv_dlerror(&lib_);
|
||||
uv_dlclose(&lib_);
|
||||
return false;
|
||||
}
|
||||
|
||||
void DLib::Close() {
|
||||
if (handle_ == nullptr) return;
|
||||
uv_dlclose(&lib_);
|
||||
handle_ = nullptr;
|
||||
}
|
||||
|
||||
void* DLib::GetSymbolAddress(const char* name) {
|
||||
void* address;
|
||||
if (0 == uv_dlsym(&lib_, name, &address)) return address;
|
||||
return nullptr;
|
||||
}
|
||||
#endif // !__POSIX__
|
||||
|
||||
using InitializerCallback = void (*)(Local<Object> exports,
|
||||
Local<Value> module,
|
||||
Local<Context> context);
|
||||
|
||||
inline InitializerCallback GetInitializerCallback(DLib* dlib) {
|
||||
const char* name = "node_register_module_v" STRINGIFY(NODE_MODULE_VERSION);
|
||||
return reinterpret_cast<InitializerCallback>(dlib->GetSymbolAddress(name));
|
||||
}
|
||||
|
||||
inline napi_addon_register_func GetNapiInitializerCallback(DLib* dlib) {
|
||||
const char* name =
|
||||
STRINGIFY(NAPI_MODULE_INITIALIZER_BASE) STRINGIFY(NAPI_MODULE_VERSION);
|
||||
return
|
||||
reinterpret_cast<napi_addon_register_func>(dlib->GetSymbolAddress(name));
|
||||
}
|
||||
|
||||
void InitModpendingOnce() {
|
||||
CHECK_EQ(0, uv_key_create(&thread_local_modpending));
|
||||
}
|
||||
|
||||
// DLOpen is process.dlopen(module, filename, flags).
|
||||
// Used to load 'module.node' dynamically shared objects.
|
||||
//
|
||||
// FIXME(bnoordhuis) Not multi-context ready. TBD how to resolve the conflict
|
||||
// when two contexts try to load the same shared object. Maybe have a shadow
|
||||
// cache that's a plain C list or hash table that's shared across contexts?
|
||||
static void DLOpen(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
auto context = env->context();
|
||||
|
||||
uv_once(&init_modpending_once, InitModpendingOnce);
|
||||
CHECK_NULL(uv_key_get(&thread_local_modpending));
|
||||
|
||||
if (args.Length() < 2) {
|
||||
env->ThrowError("process.dlopen needs at least 2 arguments.");
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t flags = DLib::kDefaultFlags;
|
||||
if (args.Length() > 2 && !args[2]->Int32Value(context).To(&flags)) {
|
||||
return env->ThrowTypeError("flag argument must be an integer.");
|
||||
}
|
||||
|
||||
Local<Object> module;
|
||||
Local<Object> exports;
|
||||
Local<Value> exports_v;
|
||||
if (!args[0]->ToObject(context).ToLocal(&module) ||
|
||||
!module->Get(context, env->exports_string()).ToLocal(&exports_v) ||
|
||||
!exports_v->ToObject(context).ToLocal(&exports)) {
|
||||
return; // Exception pending.
|
||||
}
|
||||
|
||||
node::Utf8Value filename(env->isolate(), args[1]); // Cast
|
||||
DLib dlib(*filename, flags);
|
||||
bool is_opened = dlib.Open();
|
||||
|
||||
// Objects containing v14 or later modules will have registered themselves
|
||||
// on the pending list. Activate all of them now. At present, only one
|
||||
// module per object is supported.
|
||||
node_module* const mp = static_cast<node_module*>(
|
||||
uv_key_get(&thread_local_modpending));
|
||||
uv_key_set(&thread_local_modpending, nullptr);
|
||||
|
||||
if (!is_opened) {
|
||||
Local<String> errmsg = OneByteString(env->isolate(), dlib.errmsg_.c_str());
|
||||
dlib.Close();
|
||||
#ifdef _WIN32
|
||||
// Windows needs to add the filename into the error message
|
||||
errmsg = String::Concat(
|
||||
env->isolate(), errmsg, args[1]->ToString(context).ToLocalChecked());
|
||||
#endif // _WIN32
|
||||
env->isolate()->ThrowException(Exception::Error(errmsg));
|
||||
return;
|
||||
}
|
||||
|
||||
if (mp == nullptr) {
|
||||
if (auto callback = GetInitializerCallback(&dlib)) {
|
||||
callback(exports, module, context);
|
||||
} else if (auto napi_callback = GetNapiInitializerCallback(&dlib)) {
|
||||
napi_module_register_by_symbol(exports, module, context, napi_callback);
|
||||
} else {
|
||||
dlib.Close();
|
||||
env->ThrowError("Module did not self-register.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// -1 is used for N-API modules
|
||||
if ((mp->nm_version != -1) && (mp->nm_version != NODE_MODULE_VERSION)) {
|
||||
// Even if the module did self-register, it may have done so with the wrong
|
||||
// version. We must only give up after having checked to see if it has an
|
||||
// appropriate initializer callback.
|
||||
if (auto callback = GetInitializerCallback(&dlib)) {
|
||||
callback(exports, module, context);
|
||||
return;
|
||||
}
|
||||
char errmsg[1024];
|
||||
snprintf(errmsg,
|
||||
sizeof(errmsg),
|
||||
"The module '%s'"
|
||||
"\nwas compiled against a different Node.js version using"
|
||||
"\nNODE_MODULE_VERSION %d. This version of Node.js requires"
|
||||
"\nNODE_MODULE_VERSION %d. Please try re-compiling or "
|
||||
"re-installing\nthe module (for instance, using `npm rebuild` "
|
||||
"or `npm install`).",
|
||||
*filename, mp->nm_version, NODE_MODULE_VERSION);
|
||||
|
||||
// NOTE: `mp` is allocated inside of the shared library's memory, calling
|
||||
// `dlclose` will deallocate it
|
||||
dlib.Close();
|
||||
env->ThrowError(errmsg);
|
||||
return;
|
||||
}
|
||||
if (mp->nm_flags & NM_F_BUILTIN) {
|
||||
dlib.Close();
|
||||
env->ThrowError("Built-in module self-registered.");
|
||||
return;
|
||||
}
|
||||
|
||||
mp->nm_dso_handle = dlib.handle_;
|
||||
mp->nm_link = modlist_addon;
|
||||
modlist_addon = mp;
|
||||
|
||||
if (mp->nm_context_register_func != nullptr) {
|
||||
mp->nm_context_register_func(exports, module, context, mp->nm_priv);
|
||||
} else if (mp->nm_register_func != nullptr) {
|
||||
mp->nm_register_func(exports, module, mp->nm_priv);
|
||||
} else {
|
||||
dlib.Close();
|
||||
env->ThrowError("Module has no declared entry point.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Tell coverity that 'handle' should not be freed when we return.
|
||||
// coverity[leaked_storage]
|
||||
}
|
||||
|
||||
static Maybe<bool> ProcessEmitWarningGeneric(Environment* env,
|
||||
const char* warning,
|
||||
const char* type = nullptr,
|
||||
@@ -1179,118 +908,6 @@ static void OnMessage(Local<Message> message, Local<Value> error) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Local<Object> InitModule(Environment* env,
|
||||
node_module* mod,
|
||||
Local<String> module) {
|
||||
Local<Object> exports = Object::New(env->isolate());
|
||||
// Internal bindings don't have a "module" object, only exports.
|
||||
CHECK_NULL(mod->nm_register_func);
|
||||
CHECK_NOT_NULL(mod->nm_context_register_func);
|
||||
Local<Value> unused = Undefined(env->isolate());
|
||||
mod->nm_context_register_func(exports,
|
||||
unused,
|
||||
env->context(),
|
||||
mod->nm_priv);
|
||||
return exports;
|
||||
}
|
||||
|
||||
static void ThrowIfNoSuchModule(Environment* env, const char* module_v) {
|
||||
char errmsg[1024];
|
||||
snprintf(errmsg,
|
||||
sizeof(errmsg),
|
||||
"No such module: %s",
|
||||
module_v);
|
||||
env->ThrowError(errmsg);
|
||||
}
|
||||
|
||||
static void GetBinding(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
|
||||
CHECK(args[0]->IsString());
|
||||
|
||||
Local<String> module = args[0].As<String>();
|
||||
node::Utf8Value module_v(env->isolate(), module);
|
||||
|
||||
node_module* mod = get_builtin_module(*module_v);
|
||||
Local<Object> exports;
|
||||
if (mod != nullptr) {
|
||||
exports = InitModule(env, mod, module);
|
||||
} else {
|
||||
return ThrowIfNoSuchModule(env, *module_v);
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(exports);
|
||||
}
|
||||
|
||||
static void GetInternalBinding(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
|
||||
CHECK(args[0]->IsString());
|
||||
|
||||
Local<String> module = args[0].As<String>();
|
||||
node::Utf8Value module_v(env->isolate(), module);
|
||||
Local<Object> exports;
|
||||
|
||||
node_module* mod = get_internal_module(*module_v);
|
||||
if (mod != nullptr) {
|
||||
exports = InitModule(env, mod, module);
|
||||
} else if (!strcmp(*module_v, "constants")) {
|
||||
exports = Object::New(env->isolate());
|
||||
CHECK(exports->SetPrototype(env->context(),
|
||||
Null(env->isolate())).FromJust());
|
||||
DefineConstants(env->isolate(), exports);
|
||||
} else if (!strcmp(*module_v, "natives")) {
|
||||
exports = per_process_loader.GetSourceObject(env->context());
|
||||
} else {
|
||||
return ThrowIfNoSuchModule(env, *module_v);
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(exports);
|
||||
}
|
||||
|
||||
static void GetLinkedBinding(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
|
||||
CHECK(args[0]->IsString());
|
||||
|
||||
Local<String> module_name = args[0].As<String>();
|
||||
|
||||
node::Utf8Value module_name_v(env->isolate(), module_name);
|
||||
node_module* mod = get_linked_module(*module_name_v);
|
||||
|
||||
if (mod == nullptr) {
|
||||
char errmsg[1024];
|
||||
snprintf(errmsg,
|
||||
sizeof(errmsg),
|
||||
"No such module was linked: %s",
|
||||
*module_name_v);
|
||||
return env->ThrowError(errmsg);
|
||||
}
|
||||
|
||||
Local<Object> module = Object::New(env->isolate());
|
||||
Local<Object> exports = Object::New(env->isolate());
|
||||
Local<String> exports_prop = String::NewFromUtf8(env->isolate(), "exports",
|
||||
NewStringType::kNormal).ToLocalChecked();
|
||||
module->Set(env->context(), exports_prop, exports).FromJust();
|
||||
|
||||
if (mod->nm_context_register_func != nullptr) {
|
||||
mod->nm_context_register_func(exports,
|
||||
module,
|
||||
env->context(),
|
||||
mod->nm_priv);
|
||||
} else if (mod->nm_register_func != nullptr) {
|
||||
mod->nm_register_func(exports, module, mod->nm_priv);
|
||||
} else {
|
||||
return env->ThrowError("Linked module has no declared entry point.");
|
||||
}
|
||||
|
||||
auto effective_exports = module->Get(env->context(),
|
||||
exports_prop).ToLocalChecked();
|
||||
|
||||
args.GetReturnValue().Set(effective_exports);
|
||||
}
|
||||
|
||||
static Local<Object> GetFeatures(Environment* env) {
|
||||
EscapableHandleScope scope(env->isolate());
|
||||
|
||||
@@ -1688,7 +1305,7 @@ void SetupProcessObject(Environment* env,
|
||||
env->SetMethod(process, "_kill", Kill);
|
||||
|
||||
env->SetMethodNoSideEffect(process, "cwd", Cwd);
|
||||
env->SetMethod(process, "dlopen", DLOpen);
|
||||
env->SetMethod(process, "dlopen", binding::DLOpen);
|
||||
env->SetMethod(process, "reallyExit", Exit);
|
||||
env->SetMethodNoSideEffect(process, "uptime", Uptime);
|
||||
|
||||
@@ -1825,16 +1442,18 @@ void LoadEnvironment(Environment* env) {
|
||||
global).FromJust();
|
||||
|
||||
// Create binding loaders
|
||||
Local<Function> get_binding_fn =
|
||||
env->NewFunctionTemplate(GetBinding)->GetFunction(env->context())
|
||||
.ToLocalChecked();
|
||||
Local<Function> get_binding_fn = env->NewFunctionTemplate(binding::GetBinding)
|
||||
->GetFunction(env->context())
|
||||
.ToLocalChecked();
|
||||
|
||||
Local<Function> get_linked_binding_fn =
|
||||
env->NewFunctionTemplate(GetLinkedBinding)->GetFunction(env->context())
|
||||
env->NewFunctionTemplate(binding::GetLinkedBinding)
|
||||
->GetFunction(env->context())
|
||||
.ToLocalChecked();
|
||||
|
||||
Local<Function> get_internal_binding_fn =
|
||||
env->NewFunctionTemplate(GetInternalBinding)->GetFunction(env->context())
|
||||
env->NewFunctionTemplate(binding::GetInternalBinding)
|
||||
->GetFunction(env->context())
|
||||
.ToLocalChecked();
|
||||
|
||||
Local<Value> loaders_bootstrapper_args[] = {
|
||||
@@ -2206,7 +1825,7 @@ void Init(std::vector<std::string>* argv,
|
||||
prog_start_time = static_cast<double>(uv_now(uv_default_loop()));
|
||||
|
||||
// Register built-in modules
|
||||
RegisterBuiltinModules();
|
||||
binding::RegisterBuiltinModules();
|
||||
|
||||
// Make inherited handles noninheritable.
|
||||
uv_disable_stdio_inheritance();
|
||||
@@ -2727,14 +2346,6 @@ int Start(int argc, char** argv) {
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
// Call built-in modules' _register_<module name> function to
|
||||
// do module registration explicitly.
|
||||
void RegisterBuiltinModules() {
|
||||
#define V(modname) _register_##modname();
|
||||
NODE_BUILTIN_MODULES(V)
|
||||
#undef V
|
||||
}
|
||||
|
||||
} // namespace node
|
||||
|
||||
#if !HAVE_INSPECTOR
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#include <node_buffer.h>
|
||||
#include "env.h"
|
||||
#define NAPI_EXPERIMENTAL
|
||||
#include "js_native_api_v8.h"
|
||||
#include "node_api.h"
|
||||
#include "node_binding.h"
|
||||
#include "node_errors.h"
|
||||
#include "node_internals.h"
|
||||
#include "js_native_api_v8.h"
|
||||
|
||||
struct node_napi_env__ : public napi_env__ {
|
||||
explicit node_napi_env__(v8::Local<v8::Context> context):
|
||||
|
||||
471
src/node_binding.cc
Normal file
471
src/node_binding.cc
Normal file
@@ -0,0 +1,471 @@
|
||||
#include "node_binding.h"
|
||||
#include "node_internals.h"
|
||||
#include "node_native_module.h"
|
||||
|
||||
#if defined(__POSIX__)
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_OPENSSL
|
||||
#define NODE_BUILTIN_OPENSSL_MODULES(V) V(crypto) V(tls_wrap)
|
||||
#else
|
||||
#define NODE_BUILTIN_OPENSSL_MODULES(V)
|
||||
#endif
|
||||
|
||||
#if NODE_HAVE_I18N_SUPPORT
|
||||
#define NODE_BUILTIN_ICU_MODULES(V) V(icu)
|
||||
#else
|
||||
#define NODE_BUILTIN_ICU_MODULES(V)
|
||||
#endif
|
||||
|
||||
// A list of built-in modules. In order to do module registration
|
||||
// in node::Init(), need to add built-in modules in the following list.
|
||||
// Then in binding::RegisterBuiltinModules(), it calls modules' registration
|
||||
// function. This helps the built-in modules are loaded properly when
|
||||
// node is built as static library. No need to depend on the
|
||||
// __attribute__((constructor)) like mechanism in GCC.
|
||||
#define NODE_BUILTIN_STANDARD_MODULES(V) \
|
||||
V(async_wrap) \
|
||||
V(buffer) \
|
||||
V(cares_wrap) \
|
||||
V(config) \
|
||||
V(contextify) \
|
||||
V(domain) \
|
||||
V(fs) \
|
||||
V(fs_event_wrap) \
|
||||
V(heap_utils) \
|
||||
V(http2) \
|
||||
V(http_parser) \
|
||||
V(inspector) \
|
||||
V(js_stream) \
|
||||
V(messaging) \
|
||||
V(module_wrap) \
|
||||
V(native_module) \
|
||||
V(options) \
|
||||
V(os) \
|
||||
V(performance) \
|
||||
V(pipe_wrap) \
|
||||
V(process_wrap) \
|
||||
V(serdes) \
|
||||
V(signal_wrap) \
|
||||
V(spawn_sync) \
|
||||
V(stream_pipe) \
|
||||
V(stream_wrap) \
|
||||
V(string_decoder) \
|
||||
V(symbols) \
|
||||
V(tcp_wrap) \
|
||||
V(timers) \
|
||||
V(trace_events) \
|
||||
V(tty_wrap) \
|
||||
V(types) \
|
||||
V(udp_wrap) \
|
||||
V(url) \
|
||||
V(util) \
|
||||
V(uv) \
|
||||
V(v8) \
|
||||
V(worker) \
|
||||
V(zlib)
|
||||
|
||||
#define NODE_BUILTIN_MODULES(V) \
|
||||
NODE_BUILTIN_STANDARD_MODULES(V) \
|
||||
NODE_BUILTIN_OPENSSL_MODULES(V) \
|
||||
NODE_BUILTIN_ICU_MODULES(V)
|
||||
|
||||
// This is used to load built-in modules. Instead of using
|
||||
// __attribute__((constructor)), we call the _register_<modname>
|
||||
// function for each built-in modules explicitly in
|
||||
// binding::RegisterBuiltinModules(). This is only forward declaration.
|
||||
// The definitions are in each module's implementation when calling
|
||||
// the NODE_BUILTIN_MODULE_CONTEXT_AWARE.
|
||||
#define V(modname) void _register_##modname();
|
||||
NODE_BUILTIN_MODULES(V)
|
||||
#undef V
|
||||
|
||||
namespace node {
|
||||
|
||||
using v8::Context;
|
||||
using v8::Exception;
|
||||
using v8::FunctionCallbackInfo;
|
||||
using v8::Local;
|
||||
using v8::NewStringType;
|
||||
using v8::Object;
|
||||
using v8::String;
|
||||
using v8::Value;
|
||||
|
||||
// Globals per process
|
||||
static node_module* modlist_builtin;
|
||||
static node_module* modlist_internal;
|
||||
static node_module* modlist_linked;
|
||||
static node_module* modlist_addon;
|
||||
static uv_once_t init_modpending_once = UV_ONCE_INIT;
|
||||
static uv_key_t thread_local_modpending;
|
||||
|
||||
// This is set by node::Init() which is used by embedders
|
||||
bool node_is_initialized = false;
|
||||
|
||||
extern "C" void node_module_register(void* m) {
|
||||
struct node_module* mp = reinterpret_cast<struct node_module*>(m);
|
||||
|
||||
if (mp->nm_flags & NM_F_BUILTIN) {
|
||||
mp->nm_link = modlist_builtin;
|
||||
modlist_builtin = mp;
|
||||
} else if (mp->nm_flags & NM_F_INTERNAL) {
|
||||
mp->nm_link = modlist_internal;
|
||||
modlist_internal = mp;
|
||||
} else if (!node_is_initialized) {
|
||||
// "Linked" modules are included as part of the node project.
|
||||
// Like builtins they are registered *before* node::Init runs.
|
||||
mp->nm_flags = NM_F_LINKED;
|
||||
mp->nm_link = modlist_linked;
|
||||
modlist_linked = mp;
|
||||
} else {
|
||||
uv_key_set(&thread_local_modpending, mp);
|
||||
}
|
||||
}
|
||||
|
||||
namespace binding {
|
||||
|
||||
class DLib {
|
||||
public:
|
||||
#ifdef __POSIX__
|
||||
static const int kDefaultFlags = RTLD_LAZY;
|
||||
#else
|
||||
static const int kDefaultFlags = 0;
|
||||
#endif
|
||||
|
||||
inline DLib(const char* filename, int flags)
|
||||
: filename_(filename), flags_(flags), handle_(nullptr) {}
|
||||
|
||||
inline bool Open();
|
||||
inline void Close();
|
||||
inline void* GetSymbolAddress(const char* name);
|
||||
|
||||
const std::string filename_;
|
||||
const int flags_;
|
||||
std::string errmsg_;
|
||||
void* handle_;
|
||||
#ifndef __POSIX__
|
||||
uv_lib_t lib_;
|
||||
#endif
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(DLib);
|
||||
};
|
||||
|
||||
#ifdef __POSIX__
|
||||
bool DLib::Open() {
|
||||
handle_ = dlopen(filename_.c_str(), flags_);
|
||||
if (handle_ != nullptr) return true;
|
||||
errmsg_ = dlerror();
|
||||
return false;
|
||||
}
|
||||
|
||||
void DLib::Close() {
|
||||
if (handle_ == nullptr) return;
|
||||
dlclose(handle_);
|
||||
handle_ = nullptr;
|
||||
}
|
||||
|
||||
void* DLib::GetSymbolAddress(const char* name) {
|
||||
return dlsym(handle_, name);
|
||||
}
|
||||
#else // !__POSIX__
|
||||
bool DLib::Open() {
|
||||
int ret = uv_dlopen(filename_.c_str(), &lib_);
|
||||
if (ret == 0) {
|
||||
handle_ = static_cast<void*>(lib_.handle);
|
||||
return true;
|
||||
}
|
||||
errmsg_ = uv_dlerror(&lib_);
|
||||
uv_dlclose(&lib_);
|
||||
return false;
|
||||
}
|
||||
|
||||
void DLib::Close() {
|
||||
if (handle_ == nullptr) return;
|
||||
uv_dlclose(&lib_);
|
||||
handle_ = nullptr;
|
||||
}
|
||||
|
||||
void* DLib::GetSymbolAddress(const char* name) {
|
||||
void* address;
|
||||
if (0 == uv_dlsym(&lib_, name, &address)) return address;
|
||||
return nullptr;
|
||||
}
|
||||
#endif // !__POSIX__
|
||||
|
||||
using InitializerCallback = void (*)(Local<Object> exports,
|
||||
Local<Value> module,
|
||||
Local<Context> context);
|
||||
|
||||
inline InitializerCallback GetInitializerCallback(DLib* dlib) {
|
||||
const char* name = "node_register_module_v" STRINGIFY(NODE_MODULE_VERSION);
|
||||
return reinterpret_cast<InitializerCallback>(dlib->GetSymbolAddress(name));
|
||||
}
|
||||
|
||||
inline napi_addon_register_func GetNapiInitializerCallback(DLib* dlib) {
|
||||
const char* name =
|
||||
STRINGIFY(NAPI_MODULE_INITIALIZER_BASE) STRINGIFY(NAPI_MODULE_VERSION);
|
||||
return reinterpret_cast<napi_addon_register_func>(
|
||||
dlib->GetSymbolAddress(name));
|
||||
}
|
||||
|
||||
void InitModpendingOnce() {
|
||||
CHECK_EQ(0, uv_key_create(&thread_local_modpending));
|
||||
}
|
||||
|
||||
// DLOpen is process.dlopen(module, filename, flags).
|
||||
// Used to load 'module.node' dynamically shared objects.
|
||||
//
|
||||
// FIXME(bnoordhuis) Not multi-context ready. TBD how to resolve the conflict
|
||||
// when two contexts try to load the same shared object. Maybe have a shadow
|
||||
// cache that's a plain C list or hash table that's shared across contexts?
|
||||
void DLOpen(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
auto context = env->context();
|
||||
|
||||
uv_once(&init_modpending_once, InitModpendingOnce);
|
||||
CHECK_NULL(uv_key_get(&thread_local_modpending));
|
||||
|
||||
if (args.Length() < 2) {
|
||||
env->ThrowError("process.dlopen needs at least 2 arguments.");
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t flags = DLib::kDefaultFlags;
|
||||
if (args.Length() > 2 && !args[2]->Int32Value(context).To(&flags)) {
|
||||
return env->ThrowTypeError("flag argument must be an integer.");
|
||||
}
|
||||
|
||||
Local<Object> module;
|
||||
Local<Object> exports;
|
||||
Local<Value> exports_v;
|
||||
if (!args[0]->ToObject(context).ToLocal(&module) ||
|
||||
!module->Get(context, env->exports_string()).ToLocal(&exports_v) ||
|
||||
!exports_v->ToObject(context).ToLocal(&exports)) {
|
||||
return; // Exception pending.
|
||||
}
|
||||
|
||||
node::Utf8Value filename(env->isolate(), args[1]); // Cast
|
||||
DLib dlib(*filename, flags);
|
||||
bool is_opened = dlib.Open();
|
||||
|
||||
// Objects containing v14 or later modules will have registered themselves
|
||||
// on the pending list. Activate all of them now. At present, only one
|
||||
// module per object is supported.
|
||||
node_module* const mp =
|
||||
static_cast<node_module*>(uv_key_get(&thread_local_modpending));
|
||||
uv_key_set(&thread_local_modpending, nullptr);
|
||||
|
||||
if (!is_opened) {
|
||||
Local<String> errmsg = OneByteString(env->isolate(), dlib.errmsg_.c_str());
|
||||
dlib.Close();
|
||||
#ifdef _WIN32
|
||||
// Windows needs to add the filename into the error message
|
||||
errmsg = String::Concat(
|
||||
env->isolate(), errmsg, args[1]->ToString(context).ToLocalChecked());
|
||||
#endif // _WIN32
|
||||
env->isolate()->ThrowException(Exception::Error(errmsg));
|
||||
return;
|
||||
}
|
||||
|
||||
if (mp == nullptr) {
|
||||
if (auto callback = GetInitializerCallback(&dlib)) {
|
||||
callback(exports, module, context);
|
||||
} else if (auto napi_callback = GetNapiInitializerCallback(&dlib)) {
|
||||
napi_module_register_by_symbol(exports, module, context, napi_callback);
|
||||
} else {
|
||||
dlib.Close();
|
||||
env->ThrowError("Module did not self-register.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// -1 is used for N-API modules
|
||||
if ((mp->nm_version != -1) && (mp->nm_version != NODE_MODULE_VERSION)) {
|
||||
// Even if the module did self-register, it may have done so with the wrong
|
||||
// version. We must only give up after having checked to see if it has an
|
||||
// appropriate initializer callback.
|
||||
if (auto callback = GetInitializerCallback(&dlib)) {
|
||||
callback(exports, module, context);
|
||||
return;
|
||||
}
|
||||
char errmsg[1024];
|
||||
snprintf(errmsg,
|
||||
sizeof(errmsg),
|
||||
"The module '%s'"
|
||||
"\nwas compiled against a different Node.js version using"
|
||||
"\nNODE_MODULE_VERSION %d. This version of Node.js requires"
|
||||
"\nNODE_MODULE_VERSION %d. Please try re-compiling or "
|
||||
"re-installing\nthe module (for instance, using `npm rebuild` "
|
||||
"or `npm install`).",
|
||||
*filename,
|
||||
mp->nm_version,
|
||||
NODE_MODULE_VERSION);
|
||||
|
||||
// NOTE: `mp` is allocated inside of the shared library's memory, calling
|
||||
// `dlclose` will deallocate it
|
||||
dlib.Close();
|
||||
env->ThrowError(errmsg);
|
||||
return;
|
||||
}
|
||||
if (mp->nm_flags & NM_F_BUILTIN) {
|
||||
dlib.Close();
|
||||
env->ThrowError("Built-in module self-registered.");
|
||||
return;
|
||||
}
|
||||
|
||||
mp->nm_dso_handle = dlib.handle_;
|
||||
mp->nm_link = modlist_addon;
|
||||
modlist_addon = mp;
|
||||
|
||||
if (mp->nm_context_register_func != nullptr) {
|
||||
mp->nm_context_register_func(exports, module, context, mp->nm_priv);
|
||||
} else if (mp->nm_register_func != nullptr) {
|
||||
mp->nm_register_func(exports, module, mp->nm_priv);
|
||||
} else {
|
||||
dlib.Close();
|
||||
env->ThrowError("Module has no declared entry point.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Tell coverity that 'handle' should not be freed when we return.
|
||||
// coverity[leaked_storage]
|
||||
}
|
||||
|
||||
inline struct node_module* FindModule(struct node_module* list,
|
||||
const char* name,
|
||||
int flag) {
|
||||
struct node_module* mp;
|
||||
|
||||
for (mp = list; mp != nullptr; mp = mp->nm_link) {
|
||||
if (strcmp(mp->nm_modname, name) == 0) break;
|
||||
}
|
||||
|
||||
CHECK(mp == nullptr || (mp->nm_flags & flag) != 0);
|
||||
return mp;
|
||||
}
|
||||
|
||||
node_module* get_builtin_module(const char* name) {
|
||||
return FindModule(modlist_builtin, name, NM_F_BUILTIN);
|
||||
}
|
||||
node_module* get_internal_module(const char* name) {
|
||||
return FindModule(modlist_internal, name, NM_F_INTERNAL);
|
||||
}
|
||||
node_module* get_linked_module(const char* name) {
|
||||
return FindModule(modlist_linked, name, NM_F_LINKED);
|
||||
}
|
||||
|
||||
static Local<Object> InitModule(Environment* env,
|
||||
node_module* mod,
|
||||
Local<String> module) {
|
||||
Local<Object> exports = Object::New(env->isolate());
|
||||
// Internal bindings don't have a "module" object, only exports.
|
||||
CHECK_NULL(mod->nm_register_func);
|
||||
CHECK_NOT_NULL(mod->nm_context_register_func);
|
||||
Local<Value> unused = Undefined(env->isolate());
|
||||
mod->nm_context_register_func(exports, unused, env->context(), mod->nm_priv);
|
||||
return exports;
|
||||
}
|
||||
|
||||
static void ThrowIfNoSuchModule(Environment* env, const char* module_v) {
|
||||
char errmsg[1024];
|
||||
snprintf(errmsg, sizeof(errmsg), "No such module: %s", module_v);
|
||||
env->ThrowError(errmsg);
|
||||
}
|
||||
|
||||
void GetBinding(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
|
||||
CHECK(args[0]->IsString());
|
||||
|
||||
Local<String> module = args[0].As<String>();
|
||||
node::Utf8Value module_v(env->isolate(), module);
|
||||
|
||||
node_module* mod = get_builtin_module(*module_v);
|
||||
Local<Object> exports;
|
||||
if (mod != nullptr) {
|
||||
exports = InitModule(env, mod, module);
|
||||
} else {
|
||||
return ThrowIfNoSuchModule(env, *module_v);
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(exports);
|
||||
}
|
||||
|
||||
void GetInternalBinding(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
|
||||
CHECK(args[0]->IsString());
|
||||
|
||||
Local<String> module = args[0].As<String>();
|
||||
node::Utf8Value module_v(env->isolate(), module);
|
||||
Local<Object> exports;
|
||||
|
||||
node_module* mod = get_internal_module(*module_v);
|
||||
if (mod != nullptr) {
|
||||
exports = InitModule(env, mod, module);
|
||||
} else if (!strcmp(*module_v, "constants")) {
|
||||
exports = Object::New(env->isolate());
|
||||
CHECK(
|
||||
exports->SetPrototype(env->context(), Null(env->isolate())).FromJust());
|
||||
DefineConstants(env->isolate(), exports);
|
||||
} else if (!strcmp(*module_v, "natives")) {
|
||||
exports = per_process_loader.GetSourceObject(env->context());
|
||||
} else {
|
||||
return ThrowIfNoSuchModule(env, *module_v);
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(exports);
|
||||
}
|
||||
|
||||
void GetLinkedBinding(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
|
||||
CHECK(args[0]->IsString());
|
||||
|
||||
Local<String> module_name = args[0].As<String>();
|
||||
|
||||
node::Utf8Value module_name_v(env->isolate(), module_name);
|
||||
node_module* mod = get_linked_module(*module_name_v);
|
||||
|
||||
if (mod == nullptr) {
|
||||
char errmsg[1024];
|
||||
snprintf(errmsg,
|
||||
sizeof(errmsg),
|
||||
"No such module was linked: %s",
|
||||
*module_name_v);
|
||||
return env->ThrowError(errmsg);
|
||||
}
|
||||
|
||||
Local<Object> module = Object::New(env->isolate());
|
||||
Local<Object> exports = Object::New(env->isolate());
|
||||
Local<String> exports_prop =
|
||||
String::NewFromUtf8(env->isolate(), "exports", NewStringType::kNormal)
|
||||
.ToLocalChecked();
|
||||
module->Set(env->context(), exports_prop, exports).FromJust();
|
||||
|
||||
if (mod->nm_context_register_func != nullptr) {
|
||||
mod->nm_context_register_func(
|
||||
exports, module, env->context(), mod->nm_priv);
|
||||
} else if (mod->nm_register_func != nullptr) {
|
||||
mod->nm_register_func(exports, module, mod->nm_priv);
|
||||
} else {
|
||||
return env->ThrowError("Linked module has no declared entry point.");
|
||||
}
|
||||
|
||||
auto effective_exports =
|
||||
module->Get(env->context(), exports_prop).ToLocalChecked();
|
||||
|
||||
args.GetReturnValue().Set(effective_exports);
|
||||
}
|
||||
|
||||
// Call built-in modules' _register_<module name> function to
|
||||
// do module registration explicitly.
|
||||
void RegisterBuiltinModules() {
|
||||
#define V(modname) _register_##modname();
|
||||
NODE_BUILTIN_MODULES(V)
|
||||
#undef V
|
||||
}
|
||||
|
||||
} // namespace binding
|
||||
} // namespace node
|
||||
64
src/node_binding.h
Normal file
64
src/node_binding.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef SRC_NODE_BINDING_H_
|
||||
#define SRC_NODE_BINDING_H_
|
||||
|
||||
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
||||
|
||||
#include "node.h"
|
||||
#include "node_api.h"
|
||||
#include "uv.h"
|
||||
#include "v8.h"
|
||||
|
||||
enum {
|
||||
NM_F_BUILTIN = 1 << 0,
|
||||
NM_F_LINKED = 1 << 1,
|
||||
NM_F_INTERNAL = 1 << 2,
|
||||
};
|
||||
|
||||
#define NODE_MODULE_CONTEXT_AWARE_CPP(modname, regfunc, priv, flags) \
|
||||
static node::node_module _module = { \
|
||||
NODE_MODULE_VERSION, \
|
||||
flags, \
|
||||
nullptr, \
|
||||
__FILE__, \
|
||||
nullptr, \
|
||||
(node::addon_context_register_func)(regfunc), \
|
||||
NODE_STRINGIFY(modname), \
|
||||
priv, \
|
||||
nullptr}; \
|
||||
void _register_##modname() { node_module_register(&_module); }
|
||||
|
||||
#define NODE_BUILTIN_MODULE_CONTEXT_AWARE(modname, regfunc) \
|
||||
NODE_MODULE_CONTEXT_AWARE_CPP(modname, regfunc, nullptr, NM_F_BUILTIN)
|
||||
|
||||
void napi_module_register_by_symbol(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> module,
|
||||
v8::Local<v8::Context> context,
|
||||
napi_addon_register_func init);
|
||||
|
||||
namespace node {
|
||||
|
||||
#define NODE_MODULE_CONTEXT_AWARE_INTERNAL(modname, regfunc) \
|
||||
NODE_MODULE_CONTEXT_AWARE_CPP(modname, regfunc, nullptr, NM_F_INTERNAL)
|
||||
|
||||
// Globals per process
|
||||
// This is set by node::Init() which is used by embedders
|
||||
extern bool node_is_initialized;
|
||||
|
||||
namespace binding {
|
||||
|
||||
// Call _register<module_name> functions for all of
|
||||
// the built-in modules. Because built-in modules don't
|
||||
// use the __attribute__((constructor)). Need to
|
||||
// explicitly call the _register* functions.
|
||||
void RegisterBuiltinModules();
|
||||
void GetBinding(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void GetInternalBinding(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void GetLinkedBinding(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
void DLOpen(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
|
||||
} // namespace binding
|
||||
|
||||
} // namespace node
|
||||
|
||||
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
||||
#endif // SRC_NODE_BINDING_H_
|
||||
@@ -24,15 +24,15 @@
|
||||
|
||||
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
||||
|
||||
#include "env-inl.h"
|
||||
#include "node.h"
|
||||
#include "node_binding.h"
|
||||
#include "node_mutex.h"
|
||||
#include "node_persistent.h"
|
||||
#include "tracing/trace_event.h"
|
||||
#include "util-inl.h"
|
||||
#include "env-inl.h"
|
||||
#include "uv.h"
|
||||
#include "v8.h"
|
||||
#include "tracing/trace_event.h"
|
||||
#include "node_api.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
@@ -57,12 +57,6 @@
|
||||
#define Z_MAX_LEVEL 9
|
||||
#define Z_DEFAULT_LEVEL Z_DEFAULT_COMPRESSION
|
||||
|
||||
enum {
|
||||
NM_F_BUILTIN = 1 << 0,
|
||||
NM_F_LINKED = 1 << 1,
|
||||
NM_F_INTERNAL = 1 << 2,
|
||||
};
|
||||
|
||||
struct sockaddr;
|
||||
|
||||
// Variation on NODE_DEFINE_CONSTANT that sets a String value.
|
||||
@@ -83,92 +77,6 @@ struct sockaddr;
|
||||
constant_attributes).FromJust(); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#if HAVE_OPENSSL
|
||||
#define NODE_BUILTIN_OPENSSL_MODULES(V) V(crypto) V(tls_wrap)
|
||||
#else
|
||||
#define NODE_BUILTIN_OPENSSL_MODULES(V)
|
||||
#endif
|
||||
|
||||
#if NODE_HAVE_I18N_SUPPORT
|
||||
#define NODE_BUILTIN_ICU_MODULES(V) V(icu)
|
||||
#else
|
||||
#define NODE_BUILTIN_ICU_MODULES(V)
|
||||
#endif
|
||||
|
||||
// A list of built-in modules. In order to do module registration
|
||||
// in node::Init(), need to add built-in modules in the following list.
|
||||
// Then in node::RegisterBuiltinModules(), it calls modules' registration
|
||||
// function. This helps the built-in modules are loaded properly when
|
||||
// node is built as static library. No need to depend on the
|
||||
// __attribute__((constructor)) like mechanism in GCC.
|
||||
#define NODE_BUILTIN_STANDARD_MODULES(V) \
|
||||
V(async_wrap) \
|
||||
V(buffer) \
|
||||
V(cares_wrap) \
|
||||
V(config) \
|
||||
V(contextify) \
|
||||
V(domain) \
|
||||
V(fs) \
|
||||
V(fs_event_wrap) \
|
||||
V(heap_utils) \
|
||||
V(http2) \
|
||||
V(http_parser) \
|
||||
V(inspector) \
|
||||
V(js_stream) \
|
||||
V(messaging) \
|
||||
V(module_wrap) \
|
||||
V(native_module) \
|
||||
V(options) \
|
||||
V(os) \
|
||||
V(performance) \
|
||||
V(pipe_wrap) \
|
||||
V(process_wrap) \
|
||||
V(serdes) \
|
||||
V(signal_wrap) \
|
||||
V(spawn_sync) \
|
||||
V(stream_pipe) \
|
||||
V(stream_wrap) \
|
||||
V(string_decoder) \
|
||||
V(symbols) \
|
||||
V(tcp_wrap) \
|
||||
V(timers) \
|
||||
V(trace_events) \
|
||||
V(tty_wrap) \
|
||||
V(types) \
|
||||
V(udp_wrap) \
|
||||
V(url) \
|
||||
V(util) \
|
||||
V(uv) \
|
||||
V(v8) \
|
||||
V(worker) \
|
||||
V(zlib)
|
||||
|
||||
#define NODE_BUILTIN_MODULES(V) \
|
||||
NODE_BUILTIN_STANDARD_MODULES(V) \
|
||||
NODE_BUILTIN_OPENSSL_MODULES(V) \
|
||||
NODE_BUILTIN_ICU_MODULES(V)
|
||||
|
||||
#define NODE_MODULE_CONTEXT_AWARE_CPP(modname, regfunc, priv, flags) \
|
||||
static node::node_module _module = { \
|
||||
NODE_MODULE_VERSION, \
|
||||
flags, \
|
||||
nullptr, \
|
||||
__FILE__, \
|
||||
nullptr, \
|
||||
(node::addon_context_register_func) (regfunc), \
|
||||
NODE_STRINGIFY(modname), \
|
||||
priv, \
|
||||
nullptr \
|
||||
}; \
|
||||
void _register_ ## modname() { \
|
||||
node_module_register(&_module); \
|
||||
}
|
||||
|
||||
|
||||
#define NODE_BUILTIN_MODULE_CONTEXT_AWARE(modname, regfunc) \
|
||||
NODE_MODULE_CONTEXT_AWARE_CPP(modname, regfunc, nullptr, NM_F_BUILTIN)
|
||||
|
||||
namespace node {
|
||||
|
||||
namespace native_module {
|
||||
@@ -281,12 +189,6 @@ void SetupProcessObject(Environment* env,
|
||||
const std::vector<std::string>& args,
|
||||
const std::vector<std::string>& exec_args);
|
||||
|
||||
// Call _register<module_name> functions for all of
|
||||
// the built-in modules. Because built-in modules don't
|
||||
// use the __attribute__((constructor)). Need to
|
||||
// explicitly call the _register* functions.
|
||||
void RegisterBuiltinModules();
|
||||
|
||||
enum Endianness {
|
||||
kLittleEndian, // _Not_ LITTLE_ENDIAN, clashes with endian.h.
|
||||
kBigEndian
|
||||
@@ -782,9 +684,6 @@ static inline const char* errno_string(int errorno) {
|
||||
}
|
||||
}
|
||||
|
||||
#define NODE_MODULE_CONTEXT_AWARE_INTERNAL(modname, regfunc) \
|
||||
NODE_MODULE_CONTEXT_AWARE_CPP(modname, regfunc, nullptr, NM_F_INTERNAL)
|
||||
|
||||
#define TRACING_CATEGORY_NODE "node"
|
||||
#define TRACING_CATEGORY_NODE1(one) \
|
||||
TRACING_CATEGORY_NODE "," \
|
||||
@@ -857,11 +756,6 @@ void DefineZlibConstants(v8::Local<v8::Object> target);
|
||||
|
||||
} // namespace node
|
||||
|
||||
void napi_module_register_by_symbol(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> module,
|
||||
v8::Local<v8::Context> context,
|
||||
napi_addon_register_func init);
|
||||
|
||||
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
||||
|
||||
#endif // SRC_NODE_INTERNALS_H_
|
||||
|
||||
Reference in New Issue
Block a user