Skip to content

Commit f7f454a

Browse files
thlorenzrvagg
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: #8 Reviewed-by: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
1 parent cdbfe77 commit f7f454a

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

src/node.cc

Lines changed: 64 additions & 0 deletions
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)
@@ -2040,7 +2042,15 @@ extern "C" void node_module_register(void* m) {
20402042
if (mp->nm_flags & NM_F_BUILTIN) {
20412043
mp->nm_link = modlist_builtin;
20422044
modlist_builtin = mp;
2045+
} else if (!node_is_initialized) {
2046+
// "Linked" modules are included as part of the node project.
2047+
// Like builtins they are registered *before* node::Init runs.
2048+
mp->nm_flags = NM_F_LINKED;
2049+
mp->nm_link = modlist_linked;
2050+
modlist_linked = mp;
20432051
} else {
2052+
// Once node::Init was called we can only register dynamic modules.
2053+
// See DLOpen.
20442054
CHECK_EQ(modpending, nullptr);
20452055
modpending = mp;
20462056
}
@@ -2058,6 +2068,18 @@ struct node_module* get_builtin_module(const char* name) {
20582068
return (mp);
20592069
}
20602070

2071+
struct node_module* get_linked_module(const char* name) {
2072+
struct node_module* mp;
2073+
2074+
for (mp = modlist_linked; mp != NULL; mp = mp->nm_link) {
2075+
if (strcmp(mp->nm_modname, name) == 0)
2076+
break;
2077+
}
2078+
2079+
CHECK(mp == NULL || (mp->nm_flags & NM_F_LINKED) != 0);
2080+
return mp;
2081+
}
2082+
20612083
typedef void (UV_DYNAMIC* extInit)(Handle<Object> exports);
20622084

20632085
// DLOpen is process.dlopen(module, filename).
@@ -2262,6 +2284,46 @@ static void Binding(const FunctionCallbackInfo<Value>& args) {
22622284
args.GetReturnValue().Set(exports);
22632285
}
22642286

2287+
static void LinkedBinding(const FunctionCallbackInfo<Value>& args) {
2288+
Environment* env = Environment::GetCurrent(args.GetIsolate());
2289+
2290+
Local<String> module = args[0]->ToString();
2291+
2292+
Local<Object> cache = env->binding_cache_object();
2293+
Local<Value> exports_v = cache->Get(module);
2294+
2295+
if (exports_v->IsObject())
2296+
return args.GetReturnValue().Set(exports_v.As<Object>());
2297+
2298+
node::Utf8Value module_v(module);
2299+
node_module* mod = get_linked_module(*module_v);
2300+
2301+
if (mod == NULL) {
2302+
char errmsg[1024];
2303+
snprintf(errmsg,
2304+
sizeof(errmsg),
2305+
"No such module was linked: %s",
2306+
*module_v);
2307+
return env->ThrowError(errmsg);
2308+
}
2309+
2310+
Local<Object> exports = Object::New(env->isolate());
2311+
2312+
if (mod->nm_context_register_func != NULL) {
2313+
mod->nm_context_register_func(exports,
2314+
module,
2315+
env->context(),
2316+
mod->nm_priv);
2317+
} else if (mod->nm_register_func != NULL) {
2318+
mod->nm_register_func(exports, module, mod->nm_priv);
2319+
} else {
2320+
return env->ThrowError("Linked module has no declared entry point.");
2321+
}
2322+
2323+
cache->Set(module, exports);
2324+
2325+
args.GetReturnValue().Set(exports);
2326+
}
22652327

22662328
static void ProcessTitleGetter(Local<String> property,
22672329
const PropertyCallbackInfo<Value>& info) {
@@ -2801,6 +2863,7 @@ void SetupProcessObject(Environment* env,
28012863
env->SetMethod(process, "memoryUsage", MemoryUsage);
28022864

28032865
env->SetMethod(process, "binding", Binding);
2866+
env->SetMethod(process, "_linkedBinding", LinkedBinding);
28042867

28052868
env->SetMethod(process, "_setupAsyncListener", SetupAsyncListener);
28062869
env->SetMethod(process, "_setupNextTick", SetupNextTick);
@@ -3700,6 +3763,7 @@ int Start(int argc, char** argv) {
37003763

37013764
int code;
37023765
V8::Initialize();
3766+
node_is_initialized = true;
37033767

37043768
// Fetch a reference to the main isolate, so we have a reference to it
37053769
// even when we need it to access it from another (debugger) thread.

src/node.h

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

341341
#define NM_F_BUILTIN 0x01
342+
#define NM_F_LINKED 0x02
342343

343344
struct node_module {
344345
int nm_version;
@@ -353,6 +354,7 @@ struct node_module {
353354
};
354355

355356
node_module* get_builtin_module(const char *name);
357+
node_module* get_linked_module(const char *name);
356358

357359
extern "C" NODE_EXTERN void node_module_register(void* mod);
358360

0 commit comments

Comments
 (0)