modules: adding load linked modules feature
- introduced NM_F_LINKED flag to identify linked modules - setting node_is_initialized after calling V8::Initialize in order to make the right decision during initial module registration - introduced modlist_linked in order to track modules that were pre-registered in order to complete it once node is initialized - completing registration of linked module similarly to the way it's done inside DLOpen PR-URL: https://github.com/joyent/node/pull/8386 Reviewed-by: Trevor Norris <trev.norris@gmail.com>
This commit is contained in:
parent
304c0b43aa
commit
c131c1f920
66
src/node.cc
66
src/node.cc
@ -131,8 +131,10 @@ static bool use_debug_agent = false;
|
|||||||
static bool debug_wait_connect = false;
|
static bool debug_wait_connect = false;
|
||||||
static int debug_port = 5858;
|
static int debug_port = 5858;
|
||||||
static bool v8_is_profiling = false;
|
static bool v8_is_profiling = false;
|
||||||
|
static bool node_is_initialized = false;
|
||||||
static node_module* modpending;
|
static node_module* modpending;
|
||||||
static node_module* modlist_builtin;
|
static node_module* modlist_builtin;
|
||||||
|
static node_module* modlist_linked;
|
||||||
static node_module* modlist_addon;
|
static node_module* modlist_addon;
|
||||||
|
|
||||||
#if defined(NODE_HAVE_I18N_SUPPORT)
|
#if defined(NODE_HAVE_I18N_SUPPORT)
|
||||||
@ -2051,8 +2053,16 @@ extern "C" void node_module_register(void* m) {
|
|||||||
if (mp->nm_flags & NM_F_BUILTIN) {
|
if (mp->nm_flags & NM_F_BUILTIN) {
|
||||||
mp->nm_link = modlist_builtin;
|
mp->nm_link = modlist_builtin;
|
||||||
modlist_builtin = mp;
|
modlist_builtin = 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 {
|
} else {
|
||||||
assert(modpending == NULL);
|
// Once node::Init was called we can only register dynamic modules.
|
||||||
|
// See DLOpen.
|
||||||
|
CHECK_NE(modpending, NULL);
|
||||||
modpending = mp;
|
modpending = mp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2069,6 +2079,18 @@ struct node_module* get_builtin_module(const char* name) {
|
|||||||
return (mp);
|
return (mp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct node_module* get_linked_module(const char* name) {
|
||||||
|
struct node_module* mp;
|
||||||
|
|
||||||
|
for (mp = modlist_linked; mp != NULL; mp = mp->nm_link) {
|
||||||
|
if (strcmp(mp->nm_modname, name) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(mp == NULL || (mp->nm_flags & NM_F_LINKED) != 0);
|
||||||
|
return mp;
|
||||||
|
}
|
||||||
|
|
||||||
typedef void (UV_DYNAMIC* extInit)(Handle<Object> exports);
|
typedef void (UV_DYNAMIC* extInit)(Handle<Object> exports);
|
||||||
|
|
||||||
// DLOpen is process.dlopen(module, filename).
|
// DLOpen is process.dlopen(module, filename).
|
||||||
@ -2275,6 +2297,46 @@ static void Binding(const FunctionCallbackInfo<Value>& args) {
|
|||||||
args.GetReturnValue().Set(exports);
|
args.GetReturnValue().Set(exports);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void LinkedBinding(const FunctionCallbackInfo<Value>& args) {
|
||||||
|
Environment* env = Environment::GetCurrent(args.GetIsolate());
|
||||||
|
|
||||||
|
Local<String> module = args[0]->ToString();
|
||||||
|
|
||||||
|
Local<Object> cache = env->binding_cache_object();
|
||||||
|
Local<Value> exports_v = cache->Get(module);
|
||||||
|
|
||||||
|
if (exports_v->IsObject())
|
||||||
|
return args.GetReturnValue().Set(exports_v.As<Object>());
|
||||||
|
|
||||||
|
node::Utf8Value module_v(module);
|
||||||
|
node_module* mod = get_linked_module(*module_v);
|
||||||
|
|
||||||
|
if (mod == NULL) {
|
||||||
|
char errmsg[1024];
|
||||||
|
snprintf(errmsg,
|
||||||
|
sizeof(errmsg),
|
||||||
|
"No such module was linked: %s",
|
||||||
|
*module_v);
|
||||||
|
return env->ThrowError(errmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
Local<Object> exports = Object::New(env->isolate());
|
||||||
|
|
||||||
|
if (mod->nm_context_register_func != NULL) {
|
||||||
|
mod->nm_context_register_func(exports,
|
||||||
|
module,
|
||||||
|
env->context(),
|
||||||
|
mod->nm_priv);
|
||||||
|
} else if (mod->nm_register_func != NULL) {
|
||||||
|
mod->nm_register_func(exports, module, mod->nm_priv);
|
||||||
|
} else {
|
||||||
|
return env->ThrowError("Linked module has no declared entry point.");
|
||||||
|
}
|
||||||
|
|
||||||
|
cache->Set(module, exports);
|
||||||
|
|
||||||
|
args.GetReturnValue().Set(exports);
|
||||||
|
}
|
||||||
|
|
||||||
static void ProcessTitleGetter(Local<String> property,
|
static void ProcessTitleGetter(Local<String> property,
|
||||||
const PropertyCallbackInfo<Value>& info) {
|
const PropertyCallbackInfo<Value>& info) {
|
||||||
@ -2816,6 +2878,7 @@ void SetupProcessObject(Environment* env,
|
|||||||
NODE_SET_METHOD(process, "memoryUsage", MemoryUsage);
|
NODE_SET_METHOD(process, "memoryUsage", MemoryUsage);
|
||||||
|
|
||||||
NODE_SET_METHOD(process, "binding", Binding);
|
NODE_SET_METHOD(process, "binding", Binding);
|
||||||
|
NODE_SET_METHOD(process, "_linkedBinding", LinkedBinding);
|
||||||
|
|
||||||
NODE_SET_METHOD(process, "_setupAsyncListener", SetupAsyncListener);
|
NODE_SET_METHOD(process, "_setupAsyncListener", SetupAsyncListener);
|
||||||
NODE_SET_METHOD(process, "_setupNextTick", SetupNextTick);
|
NODE_SET_METHOD(process, "_setupNextTick", SetupNextTick);
|
||||||
@ -3724,6 +3787,7 @@ int Start(int argc, char** argv) {
|
|||||||
|
|
||||||
int code;
|
int code;
|
||||||
V8::Initialize();
|
V8::Initialize();
|
||||||
|
node_is_initialized = true;
|
||||||
{
|
{
|
||||||
Locker locker(node_isolate);
|
Locker locker(node_isolate);
|
||||||
Isolate::Scope isolate_scope(node_isolate);
|
Isolate::Scope isolate_scope(node_isolate);
|
||||||
|
@ -347,6 +347,7 @@ typedef void (*addon_context_register_func)(
|
|||||||
void* priv);
|
void* priv);
|
||||||
|
|
||||||
#define NM_F_BUILTIN 0x01
|
#define NM_F_BUILTIN 0x01
|
||||||
|
#define NM_F_LINKED 0x02
|
||||||
|
|
||||||
struct node_module {
|
struct node_module {
|
||||||
int nm_version;
|
int nm_version;
|
||||||
@ -361,6 +362,7 @@ struct node_module {
|
|||||||
};
|
};
|
||||||
|
|
||||||
node_module* get_builtin_module(const char *name);
|
node_module* get_builtin_module(const char *name);
|
||||||
|
node_module* get_linked_module(const char *name);
|
||||||
|
|
||||||
extern "C" NODE_EXTERN void node_module_register(void* mod);
|
extern "C" NODE_EXTERN void node_module_register(void* mod);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user