@@ -194,6 +194,7 @@ static std::string trace_enabled_categories; // NOLINT(runtime/string)
194194static std::string trace_file_pattern = // NOLINT(runtime/string)
195195 " node_trace.${rotation}.log" ;
196196static bool abort_on_uncaught_exception = false ;
197+ static std::set<void *> addon_entry_points;
197198
198199// Bit flag used to track security reverts (see node_revert.h)
199200unsigned int reverted = 0 ;
@@ -1258,6 +1259,22 @@ inline napi_addon_register_func GetNapiInitializerCallback(DLib* dlib) {
12581259 reinterpret_cast <napi_addon_register_func>(dlib->GetSymbolAddress (name));
12591260}
12601261
1262+ // Initialize the addon, and close the DLib if this is a second-or-later
1263+ // initialization call.
1264+ template <typename Initializer, typename EntryPoint>
1265+ inline void CallAddonInitializer (Local<Object> exports,
1266+ Local<Value> module ,
1267+ Local<Context> context,
1268+ const Initializer& init,
1269+ EntryPoint entry_point,
1270+ DLib* dlib) {
1271+ init (exports, module , context);
1272+ void * generic_entry_point = reinterpret_cast <void *>(entry_point);
1273+ if (!(addon_entry_points.insert (generic_entry_point).second )) {
1274+ dlib->Close ();
1275+ }
1276+ }
1277+
12611278// DLOpen is process.dlopen(module, filename, flags).
12621279// Used to load 'module.node' dynamically shared objects.
12631280//
@@ -1313,9 +1330,16 @@ static void DLOpen(const FunctionCallbackInfo<Value>& args) {
13131330
13141331 if (mp == nullptr ) {
13151332 if (auto callback = GetInitializerCallback (&dlib)) {
1316- callback (exports, module , context);
1333+ CallAddonInitializer (exports, module , context, callback, callback, &dlib );
13171334 } else if (auto napi_callback = GetNapiInitializerCallback (&dlib)) {
1318- napi_module_register_by_symbol (exports, module , context, napi_callback);
1335+ CallAddonInitializer (exports, module , context,
1336+ [napi_callback] (Local<Object> exports,
1337+ Local<Value> module ,
1338+ Local<Context> context) {
1339+ napi_module_register_by_symbol (exports, module , context,
1340+ napi_callback);
1341+ },
1342+ napi_callback, &dlib);
13191343 } else {
13201344 dlib.Close ();
13211345 env->ThrowError (" Module did not self-register." );
@@ -1329,7 +1353,7 @@ static void DLOpen(const FunctionCallbackInfo<Value>& args) {
13291353 // version. We must only give up after having checked to see if it has an
13301354 // appropriate initializer callback.
13311355 if (auto callback = GetInitializerCallback (&dlib)) {
1332- callback (exports, module , context);
1356+ CallAddonInitializer (exports, module , context, callback, callback, &dlib );
13331357 return ;
13341358 }
13351359 char errmsg[1024 ];
@@ -1359,10 +1383,34 @@ static void DLOpen(const FunctionCallbackInfo<Value>& args) {
13591383 mp->nm_link = modlist_addon;
13601384 modlist_addon = mp;
13611385
1362- if (mp->nm_context_register_func != nullptr ) {
1363- mp->nm_context_register_func (exports, module , context, mp->nm_priv );
1386+ // N-API addons all hide behind a single callback, so its address is not
1387+ // suitable for caching. Grab the actual init callback address instead.
1388+ if (mp->nm_version == -1 ) {
1389+ auto napi_callback = napi_module_get_entry_point (mp);
1390+ CallAddonInitializer (exports, module , context,
1391+ [napi_callback] (Local<Object> exports,
1392+ Local<Value> module ,
1393+ Local<Context> context) {
1394+ napi_module_register_by_symbol (exports, module , context,
1395+ napi_callback);
1396+ },
1397+ napi_callback, &dlib);
1398+ } else if (mp->nm_context_register_func != nullptr ) {
1399+ CallAddonInitializer (exports, module , context,
1400+ [mp] (Local<Object> exports,
1401+ Local<Value> module ,
1402+ Local<Context> context) {
1403+ mp->nm_context_register_func (exports, module , context, mp->nm_priv );
1404+ },
1405+ mp->nm_context_register_func , &dlib);
13641406 } else if (mp->nm_register_func != nullptr ) {
1365- mp->nm_register_func (exports, module , mp->nm_priv );
1407+ CallAddonInitializer (exports, module , context,
1408+ [mp] (Local<Object> exports,
1409+ Local<Value> module ,
1410+ Local<Context> context) {
1411+ mp->nm_register_func (exports, module , mp->nm_priv );
1412+ },
1413+ mp->nm_register_func , &dlib);
13661414 } else {
13671415 dlib.Close ();
13681416 env->ThrowError (" Module has no declared entry point." );
0 commit comments