@@ -183,6 +183,7 @@ static bool v8_is_profiling = false;
183183static bool node_is_initialized = false ;
184184static node_module* modpending;
185185static node_module* modlist_builtin;
186+ static node_module* modlist_internal;
186187static node_module* modlist_linked;
187188static node_module* modlist_addon;
188189static bool trace_enabled = false ;
@@ -2574,6 +2575,9 @@ extern "C" void node_module_register(void* m) {
25742575 if (mp->nm_flags & NM_F_BUILTIN) {
25752576 mp->nm_link = modlist_builtin;
25762577 modlist_builtin = mp;
2578+ } else if (mp->nm_flags & NM_F_INTERNAL) {
2579+ mp->nm_link = modlist_internal;
2580+ modlist_internal = mp;
25772581 } else if (!node_is_initialized) {
25782582 // "Linked" modules are included as part of the node project.
25792583 // Like builtins they are registered *before* node::Init runs.
@@ -2585,28 +2589,28 @@ extern "C" void node_module_register(void* m) {
25852589 }
25862590}
25872591
2588- struct node_module * get_builtin_module (const char * name) {
2592+ inline struct node_module * FindModule (struct node_module * list,
2593+ const char * name,
2594+ int flag) {
25892595 struct node_module * mp;
25902596
2591- for (mp = modlist_builtin ; mp != nullptr ; mp = mp->nm_link ) {
2597+ for (mp = list ; mp != nullptr ; mp = mp->nm_link ) {
25922598 if (strcmp (mp->nm_modname , name) == 0 )
25932599 break ;
25942600 }
25952601
2596- CHECK (mp == nullptr || (mp->nm_flags & NM_F_BUILTIN ) != 0 );
2597- return (mp) ;
2602+ CHECK (mp == nullptr || (mp->nm_flags & flag ) != 0 );
2603+ return mp ;
25982604}
25992605
2600- struct node_module * get_linked_module (const char * name) {
2601- struct node_module * mp;
2602-
2603- for (mp = modlist_linked; mp != nullptr ; mp = mp->nm_link ) {
2604- if (strcmp (mp->nm_modname , name) == 0 )
2605- break ;
2606- }
2607-
2608- CHECK (mp == nullptr || (mp->nm_flags & NM_F_LINKED) != 0 );
2609- return mp;
2606+ node_module* get_builtin_module (const char * name) {
2607+ return FindModule (modlist_builtin, name, NM_F_BUILTIN);
2608+ }
2609+ node_module* get_internal_module (const char * name) {
2610+ return FindModule (modlist_internal, name, NM_F_INTERNAL);
2611+ }
2612+ node_module* get_linked_module (const char * name) {
2613+ return FindModule (modlist_linked, name, NM_F_LINKED);
26102614}
26112615
26122616struct DLib {
@@ -2880,66 +2884,119 @@ void ProcessEmitWarning(Environment* env, const char* fmt, ...) {
28802884 f.As <v8::Function>()->Call (process, 1 , &arg);
28812885}
28822886
2887+ static bool PullFromCache (Environment* env,
2888+ const FunctionCallbackInfo<Value>& args,
2889+ Local<String> module ,
2890+ Local<Object> cache) {
2891+ Local<Context> context = env->context ();
2892+ Local<Value> exports_v;
2893+ Local<Object> exports;
2894+ if (cache->Get (context, module ).ToLocal (&exports_v) &&
2895+ exports_v->IsObject () &&
2896+ exports_v->ToObject (context).ToLocal (&exports)) {
2897+ args.GetReturnValue ().Set (exports);
2898+ return true ;
2899+ }
2900+ return false ;
2901+ }
2902+
2903+ static Local<Object> InitModule (Environment* env,
2904+ node_module* mod,
2905+ Local<String> module ) {
2906+ Local<Object> exports = Object::New (env->isolate ());
2907+ // Internal bindings don't have a "module" object, only exports.
2908+ CHECK_EQ (mod->nm_register_func , nullptr );
2909+ CHECK_NE (mod->nm_context_register_func , nullptr );
2910+ Local<Value> unused = Undefined (env->isolate ());
2911+ mod->nm_context_register_func (exports,
2912+ unused,
2913+ env->context (),
2914+ mod->nm_priv );
2915+ return exports;
2916+ }
2917+
2918+ static void ThrowIfNoSuchModule (Environment* env, const char * module_v) {
2919+ char errmsg[1024 ];
2920+ snprintf (errmsg,
2921+ sizeof (errmsg),
2922+ " No such module: %s" ,
2923+ module_v);
2924+ env->ThrowError (errmsg);
2925+ }
28832926
28842927static void Binding (const FunctionCallbackInfo<Value>& args) {
28852928 Environment* env = Environment::GetCurrent (args);
28862929
2887- Local<String> module = args[ 0 ]-> ToString (env-> isolate ()) ;
2888- node::Utf8Value module_v ( env->isolate (), module );
2930+ Local<String> module ;
2931+ if (!args[ 0 ]-> ToString ( env->context ()). ToLocal (& module )) return ;
28892932
28902933 Local<Object> cache = env->binding_cache_object ();
2891- Local<Object> exports;
28922934
2893- if (cache->Has (env->context (), module ).FromJust ()) {
2894- exports = cache->Get (module )->ToObject (env->isolate ());
2895- args.GetReturnValue ().Set (exports);
2935+ if (PullFromCache (env, args, module , cache))
28962936 return ;
2897- }
28982937
28992938 // Append a string to process.moduleLoadList
29002939 char buf[1024 ];
2940+ node::Utf8Value module_v (env->isolate (), module );
29012941 snprintf (buf, sizeof (buf), " Binding %s" , *module_v);
29022942
29032943 Local<Array> modules = env->module_load_list_array ();
29042944 uint32_t l = modules->Length ();
29052945 modules->Set (l, OneByteString (env->isolate (), buf));
29062946
29072947 node_module* mod = get_builtin_module (*module_v);
2948+ Local<Object> exports;
29082949 if (mod != nullptr ) {
2909- exports = Object::New (env->isolate ());
2910- // Internal bindings don't have a "module" object, only exports.
2911- CHECK_EQ (mod->nm_register_func , nullptr );
2912- CHECK_NE (mod->nm_context_register_func , nullptr );
2913- Local<Value> unused = Undefined (env->isolate ());
2914- mod->nm_context_register_func (exports, unused,
2915- env->context (), mod->nm_priv );
2916- cache->Set (module , exports);
2950+ exports = InitModule (env, mod, module );
29172951 } else if (!strcmp (*module_v, " constants" )) {
29182952 exports = Object::New (env->isolate ());
29192953 CHECK (exports->SetPrototype (env->context (),
29202954 Null (env->isolate ())).FromJust ());
29212955 DefineConstants (env->isolate (), exports);
2922- cache->Set (module , exports);
29232956 } else if (!strcmp (*module_v, " natives" )) {
29242957 exports = Object::New (env->isolate ());
29252958 DefineJavaScript (env, exports);
2926- cache->Set (module , exports);
29272959 } else {
2928- char errmsg[1024 ];
2929- snprintf (errmsg,
2930- sizeof (errmsg),
2931- " No such module: %s" ,
2932- *module_v);
2933- return env->ThrowError (errmsg);
2960+ return ThrowIfNoSuchModule (env, *module_v);
29342961 }
2962+ cache->Set (module , exports);
2963+
2964+ args.GetReturnValue ().Set (exports);
2965+ }
2966+
2967+ static void InternalBinding (const FunctionCallbackInfo<Value>& args) {
2968+ Environment* env = Environment::GetCurrent (args);
2969+
2970+ Local<String> module ;
2971+ if (!args[0 ]->ToString (env->context ()).ToLocal (&module )) return ;
2972+
2973+ Local<Object> cache = env->internal_binding_cache_object ();
2974+
2975+ if (PullFromCache (env, args, module , cache))
2976+ return ;
2977+
2978+ // Append a string to process.moduleLoadList
2979+ char buf[1024 ];
2980+ node::Utf8Value module_v (env->isolate (), module );
2981+ snprintf (buf, sizeof (buf), " Internal Binding %s" , *module_v);
2982+
2983+ Local<Array> modules = env->module_load_list_array ();
2984+ uint32_t l = modules->Length ();
2985+ modules->Set (l, OneByteString (env->isolate (), buf));
2986+
2987+ node_module* mod = get_internal_module (*module_v);
2988+ if (mod == nullptr ) return ThrowIfNoSuchModule (env, *module_v);
2989+ Local<Object> exports = InitModule (env, mod, module );
2990+ cache->Set (module , exports);
29352991
29362992 args.GetReturnValue ().Set (exports);
29372993}
29382994
29392995static void LinkedBinding (const FunctionCallbackInfo<Value>& args) {
29402996 Environment* env = Environment::GetCurrent (args.GetIsolate ());
29412997
2942- Local<String> module_name = args[0 ]->ToString (env->isolate ());
2998+ Local<String> module_name;
2999+ if (!args[0 ]->ToString (env->context ()).ToLocal (&module_name)) return ;
29433000
29443001 Local<Object> cache = env->binding_cache_object ();
29453002 Local<Value> exports_v = cache->Get (module_name);
@@ -3674,6 +3731,7 @@ void SetupProcessObject(Environment* env,
36743731
36753732 env->SetMethod (process, " binding" , Binding);
36763733 env->SetMethod (process, " _linkedBinding" , LinkedBinding);
3734+ env->SetMethod (process, " _internalBinding" , InternalBinding);
36773735
36783736 env->SetMethod (process, " _setupProcessObject" , SetupProcessObject);
36793737 env->SetMethod (process, " _setupNextTick" , SetupNextTick);
0 commit comments