Created
February 3, 2017 18:45
-
-
Save ghaiklor/048d68dbec37168f1720f039d14b68bf to your computer and use it in GitHub Desktop.
process.dlopen sources
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// DLOpen is process.dlopen(module, filename). | |
// Used to load 'module.node' dynamically shared objects. | |
void DLOpen(const FunctionCallbackInfo<Value>& args) { | |
Environment* env = Environment::GetCurrent(args); | |
uv_lib_t lib; | |
CHECK_EQ(modpending, nullptr); | |
if (args.Length() != 2) { | |
env->ThrowError("process.dlopen takes exactly 2 arguments."); | |
return; | |
} | |
Local<Object> module = args[0]->ToObject(env->isolate()); // Cast | |
node::Utf8Value filename(env->isolate(), args[1]); // Cast | |
const bool is_dlopen_error = uv_dlopen(*filename, &lib); | |
// 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 = modpending; | |
modpending = nullptr; | |
if (is_dlopen_error) { | |
Local<String> errmsg = OneByteString(env->isolate(), uv_dlerror(&lib)); | |
uv_dlclose(&lib); | |
#ifdef _WIN32 | |
// Windows needs to add the filename into the error message | |
errmsg = String::Concat(errmsg, args[1]->ToString(env->isolate())); | |
#endif // _WIN32 | |
env->isolate()->ThrowException(Exception::Error(errmsg)); | |
return; | |
} | |
if (mp == nullptr) { | |
uv_dlclose(&lib); | |
env->ThrowError("Module did not self-register."); | |
return; | |
} | |
if (mp->nm_version != NODE_MODULE_VERSION) { | |
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 | |
// `uv_dlclose` will deallocate it | |
uv_dlclose(&lib); | |
env->ThrowError(errmsg); | |
return; | |
} | |
if (mp->nm_flags & NM_F_BUILTIN) { | |
uv_dlclose(&lib); | |
env->ThrowError("Built-in module self-registered."); | |
return; | |
} | |
mp->nm_dso_handle = lib.handle; | |
mp->nm_link = modlist_addon; | |
modlist_addon = mp; | |
Local<String> exports_string = env->exports_string(); | |
Local<Object> exports = module->Get(exports_string)->ToObject(env->isolate()); | |
if (mp->nm_context_register_func != nullptr) { | |
mp->nm_context_register_func(exports, module, env->context(), mp->nm_priv); | |
} else if (mp->nm_register_func != nullptr) { | |
mp->nm_register_func(exports, module, mp->nm_priv); | |
} else { | |
uv_dlclose(&lib); | |
env->ThrowError("Module has no declared entry point."); | |
return; | |
} | |
// Tell coverity that 'handle' should not be freed when we return. | |
// coverity[leaked_storage] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment