@@ -179,6 +179,7 @@ static bool v8_is_profiling = false;
179
179
static bool node_is_initialized = false ;
180
180
static node_module* modpending;
181
181
static node_module* modlist_builtin;
182
+ static node_module* modlist_internal;
182
183
static node_module* modlist_linked;
183
184
static node_module* modlist_addon;
184
185
static bool trace_enabled = false ;
@@ -2565,6 +2566,9 @@ extern "C" void node_module_register(void* m) {
2565
2566
if (mp->nm_flags & NM_F_BUILTIN) {
2566
2567
mp->nm_link = modlist_builtin;
2567
2568
modlist_builtin = mp;
2569
+ } else if (mp->nm_flags & NM_F_INTERNAL) {
2570
+ mp->nm_link = modlist_internal;
2571
+ modlist_internal = mp;
2568
2572
} else if (!node_is_initialized) {
2569
2573
// "Linked" modules are included as part of the node project.
2570
2574
// Like builtins they are registered *before* node::Init runs.
@@ -2576,28 +2580,28 @@ extern "C" void node_module_register(void* m) {
2576
2580
}
2577
2581
}
2578
2582
2579
- struct node_module * get_builtin_module (const char * name) {
2583
+ inline struct node_module * FindModule (struct node_module * list,
2584
+ const char * name,
2585
+ int flag) {
2580
2586
struct node_module * mp;
2581
2587
2582
- for (mp = modlist_builtin ; mp != nullptr ; mp = mp->nm_link ) {
2588
+ for (mp = list ; mp != nullptr ; mp = mp->nm_link ) {
2583
2589
if (strcmp (mp->nm_modname , name) == 0 )
2584
2590
break ;
2585
2591
}
2586
2592
2587
- CHECK (mp == nullptr || (mp->nm_flags & NM_F_BUILTIN ) != 0 );
2588
- return (mp) ;
2593
+ CHECK (mp == nullptr || (mp->nm_flags & flag ) != 0 );
2594
+ return mp ;
2589
2595
}
2590
2596
2591
- struct node_module * get_linked_module (const char * name) {
2592
- struct node_module * mp;
2593
-
2594
- for (mp = modlist_linked; mp != nullptr ; mp = mp->nm_link ) {
2595
- if (strcmp (mp->nm_modname , name) == 0 )
2596
- break ;
2597
- }
2598
-
2599
- CHECK (mp == nullptr || (mp->nm_flags & NM_F_LINKED) != 0 );
2600
- return mp;
2597
+ node_module* get_builtin_module (const char * name) {
2598
+ return FindModule (modlist_builtin, name, NM_F_BUILTIN);
2599
+ }
2600
+ node_module* get_internal_module (const char * name) {
2601
+ return FindModule (modlist_internal, name, NM_F_INTERNAL);
2602
+ }
2603
+ node_module* get_linked_module (const char * name) {
2604
+ return FindModule (modlist_linked, name, NM_F_LINKED);
2601
2605
}
2602
2606
2603
2607
// DLOpen is process.dlopen(module, filename).
@@ -2822,66 +2826,119 @@ void ProcessEmitWarning(Environment* env, const char* fmt, ...) {
2822
2826
f.As <v8::Function>()->Call (process, 1 , &arg);
2823
2827
}
2824
2828
2829
+ static bool PullFromCache (Environment* env,
2830
+ const FunctionCallbackInfo<Value>& args,
2831
+ Local<String> module ,
2832
+ Local<Object> cache) {
2833
+ Local<Context> context = env->context ();
2834
+ Local<Value> exports_v;
2835
+ Local<Object> exports;
2836
+ if (cache->Get (context, module ).ToLocal (&exports_v) &&
2837
+ exports_v->IsObject () &&
2838
+ exports_v->ToObject (context).ToLocal (&exports)) {
2839
+ args.GetReturnValue ().Set (exports);
2840
+ return true ;
2841
+ }
2842
+ return false ;
2843
+ }
2844
+
2845
+ static Local<Object> InitModule (Environment* env,
2846
+ node_module* mod,
2847
+ Local<String> module ) {
2848
+ Local<Object> exports = Object::New (env->isolate ());
2849
+ // Internal bindings don't have a "module" object, only exports.
2850
+ CHECK_EQ (mod->nm_register_func , nullptr );
2851
+ CHECK_NE (mod->nm_context_register_func , nullptr );
2852
+ Local<Value> unused = Undefined (env->isolate ());
2853
+ mod->nm_context_register_func (exports,
2854
+ unused,
2855
+ env->context (),
2856
+ mod->nm_priv );
2857
+ return exports;
2858
+ }
2859
+
2860
+ static void ThrowIfNoSuchModule (Environment* env, const char * module_v) {
2861
+ char errmsg[1024 ];
2862
+ snprintf (errmsg,
2863
+ sizeof (errmsg),
2864
+ " No such module: %s" ,
2865
+ module_v);
2866
+ env->ThrowError (errmsg);
2867
+ }
2825
2868
2826
2869
static void Binding (const FunctionCallbackInfo<Value>& args) {
2827
2870
Environment* env = Environment::GetCurrent (args);
2828
2871
2829
- Local<String> module = args[ 0 ]-> ToString (env-> isolate ()) ;
2830
- node::Utf8Value module_v ( env->isolate (), module );
2872
+ Local<String> module ;
2873
+ if (!args[ 0 ]-> ToString ( env->context ()). ToLocal (& module )) return ;
2831
2874
2832
2875
Local<Object> cache = env->binding_cache_object ();
2833
- Local<Object> exports;
2834
2876
2835
- if (cache->Has (env->context (), module ).FromJust ()) {
2836
- exports = cache->Get (module )->ToObject (env->isolate ());
2837
- args.GetReturnValue ().Set (exports);
2877
+ if (PullFromCache (env, args, module , cache))
2838
2878
return ;
2839
- }
2840
2879
2841
2880
// Append a string to process.moduleLoadList
2842
2881
char buf[1024 ];
2882
+ node::Utf8Value module_v (env->isolate (), module );
2843
2883
snprintf (buf, sizeof (buf), " Binding %s" , *module_v);
2844
2884
2845
2885
Local<Array> modules = env->module_load_list_array ();
2846
2886
uint32_t l = modules->Length ();
2847
2887
modules->Set (l, OneByteString (env->isolate (), buf));
2848
2888
2849
2889
node_module* mod = get_builtin_module (*module_v);
2890
+ Local<Object> exports;
2850
2891
if (mod != nullptr ) {
2851
- exports = Object::New (env->isolate ());
2852
- // Internal bindings don't have a "module" object, only exports.
2853
- CHECK_EQ (mod->nm_register_func , nullptr );
2854
- CHECK_NE (mod->nm_context_register_func , nullptr );
2855
- Local<Value> unused = Undefined (env->isolate ());
2856
- mod->nm_context_register_func (exports, unused,
2857
- env->context (), mod->nm_priv );
2858
- cache->Set (module , exports);
2892
+ exports = InitModule (env, mod, module );
2859
2893
} else if (!strcmp (*module_v, " constants" )) {
2860
2894
exports = Object::New (env->isolate ());
2861
2895
CHECK (exports->SetPrototype (env->context (),
2862
2896
Null (env->isolate ())).FromJust ());
2863
2897
DefineConstants (env->isolate (), exports);
2864
- cache->Set (module , exports);
2865
2898
} else if (!strcmp (*module_v, " natives" )) {
2866
2899
exports = Object::New (env->isolate ());
2867
2900
DefineJavaScript (env, exports);
2868
- cache->Set (module , exports);
2869
2901
} else {
2870
- char errmsg[1024 ];
2871
- snprintf (errmsg,
2872
- sizeof (errmsg),
2873
- " No such module: %s" ,
2874
- *module_v);
2875
- return env->ThrowError (errmsg);
2902
+ return ThrowIfNoSuchModule (env, *module_v);
2876
2903
}
2904
+ cache->Set (module , exports);
2905
+
2906
+ args.GetReturnValue ().Set (exports);
2907
+ }
2908
+
2909
+ static void InternalBinding (const FunctionCallbackInfo<Value>& args) {
2910
+ Environment* env = Environment::GetCurrent (args);
2911
+
2912
+ Local<String> module ;
2913
+ if (!args[0 ]->ToString (env->context ()).ToLocal (&module )) return ;
2914
+
2915
+ Local<Object> cache = env->internal_binding_cache_object ();
2916
+
2917
+ if (PullFromCache (env, args, module , cache))
2918
+ return ;
2919
+
2920
+ // Append a string to process.moduleLoadList
2921
+ char buf[1024 ];
2922
+ node::Utf8Value module_v (env->isolate (), module );
2923
+ snprintf (buf, sizeof (buf), " Internal Binding %s" , *module_v);
2924
+
2925
+ Local<Array> modules = env->module_load_list_array ();
2926
+ uint32_t l = modules->Length ();
2927
+ modules->Set (l, OneByteString (env->isolate (), buf));
2928
+
2929
+ node_module* mod = get_internal_module (*module_v);
2930
+ if (mod == nullptr ) return ThrowIfNoSuchModule (env, *module_v);
2931
+ Local<Object> exports = InitModule (env, mod, module );
2932
+ cache->Set (module , exports);
2877
2933
2878
2934
args.GetReturnValue ().Set (exports);
2879
2935
}
2880
2936
2881
2937
static void LinkedBinding (const FunctionCallbackInfo<Value>& args) {
2882
2938
Environment* env = Environment::GetCurrent (args.GetIsolate ());
2883
2939
2884
- Local<String> module_name = args[0 ]->ToString (env->isolate ());
2940
+ Local<String> module_name;
2941
+ if (!args[0 ]->ToString (env->context ()).ToLocal (&module_name)) return ;
2885
2942
2886
2943
Local<Object> cache = env->binding_cache_object ();
2887
2944
Local<Value> exports_v = cache->Get (module_name);
@@ -3616,6 +3673,7 @@ void SetupProcessObject(Environment* env,
3616
3673
3617
3674
env->SetMethod (process, " binding" , Binding);
3618
3675
env->SetMethod (process, " _linkedBinding" , LinkedBinding);
3676
+ env->SetMethod (process, " _internalBinding" , InternalBinding);
3619
3677
3620
3678
env->SetMethod (process, " _setupProcessObject" , SetupProcessObject);
3621
3679
env->SetMethod (process, " _setupNextTick" , SetupNextTick);
0 commit comments