Skip to content

Commit c131c1f

Browse files
thlorenztrevnorris
authored andcommitted
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: nodejs/node-v0.x-archive#8386 Reviewed-by: Trevor Norris <[email protected]>
1 parent 304c0b4 commit c131c1f

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

src/node.cc

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,10 @@ static bool use_debug_agent = false;
131131
static bool debug_wait_connect = false;
132132
static int debug_port = 5858;
133133
static bool v8_is_profiling = false;
134+
static bool node_is_initialized = false;
134135
static node_module* modpending;
135136
static node_module* modlist_builtin;
137+
static node_module* modlist_linked;
136138
static node_module* modlist_addon;
137139

138140
#if defined(NODE_HAVE_I18N_SUPPORT)
@@ -2051,8 +2053,16 @@ extern "C" void node_module_register(void* m) {
20512053
if (mp->nm_flags & NM_F_BUILTIN) {
20522054
mp->nm_link = modlist_builtin;
20532055
modlist_builtin = mp;
2056+
} else if (!node_is_initialized) {
2057+
// "Linked" modules are included as part of the node project.
2058+
// Like builtins they are registered *before* node::Init runs.
2059+
mp->nm_flags = NM_F_LINKED;
2060+
mp->nm_link = modlist_linked;
2061+
modlist_linked = mp;
20542062
} else {
2055-
assert(modpending == NULL);
2063+
// Once node::Init was called we can only register dynamic modules.
2064+
// See DLOpen.
2065+
CHECK_NE(modpending, NULL);
20562066
modpending = mp;
20572067
}
20582068
}
@@ -2069,6 +2079,18 @@ struct node_module* get_builtin_module(const char* name) {
20692079
return (mp);
20702080
}
20712081

2082+
struct node_module* get_linked_module(const char* name) {
2083+
struct node_module* mp;
2084+
2085+
for (mp = modlist_linked; mp != NULL; mp = mp->nm_link) {
2086+
if (strcmp(mp->nm_modname, name) == 0)
2087+
break;
2088+
}
2089+
2090+
CHECK(mp == NULL || (mp->nm_flags & NM_F_LINKED) != 0);
2091+
return mp;
2092+
}
2093+
20722094
typedef void (UV_DYNAMIC* extInit)(Handle<Object> exports);
20732095

20742096
// DLOpen is process.dlopen(module, filename).
@@ -2275,6 +2297,46 @@ static void Binding(const FunctionCallbackInfo<Value>& args) {
22752297
args.GetReturnValue().Set(exports);
22762298
}
22772299

2300+
static void LinkedBinding(const FunctionCallbackInfo<Value>& args) {
2301+
Environment* env = Environment::GetCurrent(args.GetIsolate());
2302+
2303+
Local<String> module = args[0]->ToString();
2304+
2305+
Local<Object> cache = env->binding_cache_object();
2306+
Local<Value> exports_v = cache->Get(module);
2307+
2308+
if (exports_v->IsObject())
2309+
return args.GetReturnValue().Set(exports_v.As<Object>());
2310+
2311+
node::Utf8Value module_v(module);
2312+
node_module* mod = get_linked_module(*module_v);
2313+
2314+
if (mod == NULL) {
2315+
char errmsg[1024];
2316+
snprintf(errmsg,
2317+
sizeof(errmsg),
2318+
"No such module was linked: %s",
2319+
*module_v);
2320+
return env->ThrowError(errmsg);
2321+
}
2322+
2323+
Local<Object> exports = Object::New(env->isolate());
2324+
2325+
if (mod->nm_context_register_func != NULL) {
2326+
mod->nm_context_register_func(exports,
2327+
module,
2328+
env->context(),
2329+
mod->nm_priv);
2330+
} else if (mod->nm_register_func != NULL) {
2331+
mod->nm_register_func(exports, module, mod->nm_priv);
2332+
} else {
2333+
return env->ThrowError("Linked module has no declared entry point.");
2334+
}
2335+
2336+
cache->Set(module, exports);
2337+
2338+
args.GetReturnValue().Set(exports);
2339+
}
22782340

22792341
static void ProcessTitleGetter(Local<String> property,
22802342
const PropertyCallbackInfo<Value>& info) {
@@ -2816,6 +2878,7 @@ void SetupProcessObject(Environment* env,
28162878
NODE_SET_METHOD(process, "memoryUsage", MemoryUsage);
28172879

28182880
NODE_SET_METHOD(process, "binding", Binding);
2881+
NODE_SET_METHOD(process, "_linkedBinding", LinkedBinding);
28192882

28202883
NODE_SET_METHOD(process, "_setupAsyncListener", SetupAsyncListener);
28212884
NODE_SET_METHOD(process, "_setupNextTick", SetupNextTick);
@@ -3724,6 +3787,7 @@ int Start(int argc, char** argv) {
37243787

37253788
int code;
37263789
V8::Initialize();
3790+
node_is_initialized = true;
37273791
{
37283792
Locker locker(node_isolate);
37293793
Isolate::Scope isolate_scope(node_isolate);

src/node.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ typedef void (*addon_context_register_func)(
347347
void* priv);
348348

349349
#define NM_F_BUILTIN 0x01
350+
#define NM_F_LINKED 0x02
350351

351352
struct node_module {
352353
int nm_version;
@@ -361,6 +362,7 @@ struct node_module {
361362
};
362363

363364
node_module* get_builtin_module(const char *name);
365+
node_module* get_linked_module(const char *name);
364366

365367
extern "C" NODE_EXTERN void node_module_register(void* mod);
366368

0 commit comments

Comments
 (0)