@@ -130,6 +130,9 @@ static bool use_debug_agent = false;
130130static bool debug_wait_connect = false ;
131131static int debug_port = 5858 ;
132132static bool v8_is_profiling = false ;
133+ static node_module* modpending;
134+ static node_module* modlist_builtin;
135+ static node_module* modlist_addon;
133136
134137// used by C++ modules as well
135138bool no_deprecation = false ;
@@ -1882,6 +1885,29 @@ void Hrtime(const FunctionCallbackInfo<Value>& args) {
18821885 args.GetReturnValue ().Set (tuple);
18831886}
18841887
1888+ extern " C" void node_module_register (void * m) {
1889+ struct node_module * mp = reinterpret_cast <struct node_module *>(m);
1890+
1891+ if (mp->nm_flags & NM_F_BUILTIN) {
1892+ mp->nm_link = modlist_builtin;
1893+ modlist_builtin = mp;
1894+ } else {
1895+ assert (modpending == NULL );
1896+ modpending = mp;
1897+ }
1898+ }
1899+
1900+ struct node_module * get_builtin_module (const char * name) {
1901+ struct node_module * mp;
1902+
1903+ for (mp = modlist_builtin; mp != NULL ; mp = mp->nm_link ) {
1904+ if (strcmp (mp->nm_modname , name) == 0 )
1905+ break ;
1906+ }
1907+
1908+ assert (mp == NULL || (mp->nm_flags & NM_F_BUILTIN) != 0 );
1909+ return (mp);
1910+ }
18851911
18861912typedef void (UV_DYNAMIC* extInit)(Handle<Object> exports);
18871913
@@ -1894,12 +1920,12 @@ typedef void (UV_DYNAMIC* extInit)(Handle<Object> exports);
18941920void DLOpen (const FunctionCallbackInfo<Value>& args) {
18951921 HandleScope handle_scope (args.GetIsolate ());
18961922 Environment* env = Environment::GetCurrent (args.GetIsolate ());
1897- char symbol[ 1024 ], *base, *pos ;
1923+ struct node_module * mp ;
18981924 uv_lib_t lib;
1899- int r;
19001925
19011926 if (args.Length () < 2 ) {
1902- return ThrowError (" process.dlopen takes exactly 2 arguments." );
1927+ ThrowError (" process.dlopen takes exactly 2 arguments." );
1928+ return ;
19031929 }
19041930
19051931 Local<Object> module = args[0 ]->ToObject (); // Cast
@@ -1918,68 +1944,43 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
19181944 return ;
19191945 }
19201946
1921- String::Utf8Value path (args[1 ]);
1922- base = *path;
1923-
1924- /* Find the shared library filename within the full path. */
1925- #ifdef __POSIX__
1926- pos = strrchr (base, ' /' );
1927- if (pos != NULL ) {
1928- base = pos + 1 ;
1929- }
1930- #else // Windows
1931- for (;;) {
1932- pos = strpbrk (base, " \\ /:" );
1933- if (pos == NULL ) {
1934- break ;
1935- }
1936- base = pos + 1 ;
1937- }
1938- #endif // __POSIX__
1939-
1940- /* Strip the .node extension. */
1941- pos = strrchr (base, ' .' );
1942- if (pos != NULL ) {
1943- *pos = ' \0 ' ;
1944- }
1945-
1946- /* Add the `_module` suffix to the extension name. */
1947- r = snprintf (symbol, sizeof symbol, " %s_module" , base);
1948- if (r <= 0 || static_cast <size_t >(r) >= sizeof symbol) {
1949- return ThrowError (" Out of memory." );
1950- }
1951-
1952- /* Replace dashes with underscores. When loading foo-bar.node,
1953- * look for foo_bar_module, not foo-bar_module.
1947+ /*
1948+ * Objects containing v14 or later modules will have registered themselves
1949+ * on the pending list. Activate all of them now. At present, only one
1950+ * module per object is supported.
19541951 */
1955- for (pos = symbol; *pos != ' \0 ' ; ++pos) {
1956- if (*pos == ' -' )
1957- *pos = ' _' ;
1958- }
1952+ mp = modpending;
1953+ modpending = NULL ;
19591954
1960- node_module_struct *mod;
1961- if (uv_dlsym (&lib, symbol, reinterpret_cast <void **>(&mod))) {
1962- char errmsg[1024 ];
1963- snprintf (errmsg, sizeof (errmsg), " Symbol %s not found." , symbol);
1964- return ThrowError (errmsg);
1955+ if (mp == NULL ) {
1956+ ThrowError (" Module did not self-register." );
1957+ return ;
19651958 }
1966-
1967- if (mod->version != NODE_MODULE_VERSION) {
1959+ if (mp->nm_version != NODE_MODULE_VERSION) {
19681960 char errmsg[1024 ];
19691961 snprintf (errmsg,
19701962 sizeof (errmsg),
19711963 " Module version mismatch. Expected %d, got %d." ,
1972- NODE_MODULE_VERSION, mod->version );
1973- return ThrowError (errmsg);
1964+ NODE_MODULE_VERSION, mp->nm_version );
1965+ ThrowError (errmsg);
1966+ return ;
1967+ }
1968+ if (mp->nm_flags & NM_F_BUILTIN) {
1969+ ThrowError (" Built-in module self-registered." );
1970+ return ;
19741971 }
19751972
1976- // Execute the C++ module
1977- if (mod->register_context_func != NULL ) {
1978- mod->register_context_func (exports, module , env->context ());
1979- } else if (mod->register_func != NULL ) {
1980- mod->register_func (exports, module );
1973+ mp->nm_dso_handle = lib.handle ;
1974+ mp->nm_link = modlist_addon;
1975+ modlist_addon = mp;
1976+
1977+ if (mp->nm_context_register_func != NULL ) {
1978+ mp->nm_context_register_func (exports, module , env->context (), mp->nm_priv );
1979+ } else if (mp->nm_register_func != NULL ) {
1980+ mp->nm_register_func (exports, module , mp->nm_priv );
19811981 } else {
1982- return ThrowError (" Module has no declared entry point." );
1982+ ThrowError (" Module has no declared entry point." );
1983+ return ;
19831984 }
19841985
19851986 // Tell coverity that 'handle' should not be freed when we return.
@@ -2082,14 +2083,15 @@ static void Binding(const FunctionCallbackInfo<Value>& args) {
20822083 uint32_t l = modules->Length ();
20832084 modules->Set (l, OneByteString (node_isolate, buf));
20842085
2085- node_module_struct * mod = get_builtin_module (*module_v);
2086+ node_module * mod = get_builtin_module (*module_v);
20862087 if (mod != NULL ) {
20872088 exports = Object::New ();
20882089 // Internal bindings don't have a "module" object, only exports.
2089- assert (mod->register_func == NULL );
2090- assert (mod->register_context_func != NULL );
2090+ assert (mod->nm_register_func == NULL );
2091+ assert (mod->nm_context_register_func != NULL );
20912092 Local<Value> unused = Undefined (env->isolate ());
2092- mod->register_context_func (exports, unused, env->context ());
2093+ mod->nm_context_register_func (exports, unused,
2094+ env->context (), mod->nm_priv );
20932095 cache->Set (module , exports);
20942096 } else if (!strcmp (*module_v, " constants" )) {
20952097 exports = Object::New ();
0 commit comments