@@ -131,8 +131,10 @@ static bool use_debug_agent = false;
131
131
static bool debug_wait_connect = false ;
132
132
static int debug_port = 5858 ;
133
133
static bool v8_is_profiling = false ;
134
+ static bool node_is_initialized = false ;
134
135
static node_module* modpending;
135
136
static node_module* modlist_builtin;
137
+ static node_module* modlist_linked;
136
138
static node_module* modlist_addon;
137
139
138
140
#if defined(NODE_HAVE_I18N_SUPPORT)
@@ -2040,7 +2042,15 @@ extern "C" void node_module_register(void* m) {
2040
2042
if (mp->nm_flags & NM_F_BUILTIN) {
2041
2043
mp->nm_link = modlist_builtin;
2042
2044
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;
2043
2051
} else {
2052
+ // Once node::Init was called we can only register dynamic modules.
2053
+ // See DLOpen.
2044
2054
CHECK_EQ (modpending, nullptr );
2045
2055
modpending = mp;
2046
2056
}
@@ -2058,6 +2068,18 @@ struct node_module* get_builtin_module(const char* name) {
2058
2068
return (mp);
2059
2069
}
2060
2070
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
+
2061
2083
typedef void (UV_DYNAMIC* extInit)(Handle<Object> exports);
2062
2084
2063
2085
// DLOpen is process.dlopen(module, filename).
@@ -2262,6 +2284,46 @@ static void Binding(const FunctionCallbackInfo<Value>& args) {
2262
2284
args.GetReturnValue ().Set (exports);
2263
2285
}
2264
2286
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
+ }
2265
2327
2266
2328
static void ProcessTitleGetter (Local<String> property,
2267
2329
const PropertyCallbackInfo<Value>& info) {
@@ -2801,6 +2863,7 @@ void SetupProcessObject(Environment* env,
2801
2863
env->SetMethod (process, " memoryUsage" , MemoryUsage);
2802
2864
2803
2865
env->SetMethod (process, " binding" , Binding);
2866
+ env->SetMethod (process, " _linkedBinding" , LinkedBinding);
2804
2867
2805
2868
env->SetMethod (process, " _setupAsyncListener" , SetupAsyncListener);
2806
2869
env->SetMethod (process, " _setupNextTick" , SetupNextTick);
@@ -3700,6 +3763,7 @@ int Start(int argc, char** argv) {
3700
3763
3701
3764
int code;
3702
3765
V8::Initialize ();
3766
+ node_is_initialized = true ;
3703
3767
3704
3768
// Fetch a reference to the main isolate, so we have a reference to it
3705
3769
// even when we need it to access it from another (debugger) thread.
0 commit comments