@@ -327,16 +327,48 @@ inline Environment* Environment::GetCurrent(
327327 return GetFromCallbackData (info.Data ());
328328}
329329
330- inline Environment* Environment::GetFromCallbackData (v8::Local<v8::Value> val) {
330+ Environment* Environment::GetFromCallbackData (v8::Local<v8::Value> val) {
331331 DCHECK (val->IsObject ());
332332 v8::Local<v8::Object> obj = val.As <v8::Object>();
333- DCHECK_GE (obj->InternalFieldCount (), 1 );
334- Environment* env =
335- static_cast <Environment* >(obj-> GetAlignedPointerFromInternalField ( 0 ) );
333+ DCHECK_GE (obj->InternalFieldCount (),
334+ BaseObject:: kInternalFieldCount );
335+ Environment* env = Unwrap<BaseObject >(obj)-> env ( );
336336 DCHECK (env->as_callback_data_template ()->HasInstance (obj));
337337 return env;
338338}
339339
340+ template <typename T>
341+ Environment::BindingScope<T>::BindingScope(Environment* env) : env(env) {
342+ v8::Local<v8::Object> callback_data;
343+ if (!env->MakeBindingCallbackData <T>().ToLocal (&callback_data))
344+ return ;
345+ data = Unwrap<T>(callback_data);
346+
347+ // No nesting allowed currently.
348+ CHECK_EQ (env->current_callback_data (), env->as_callback_data ());
349+ env->set_current_callback_data (callback_data);
350+ }
351+
352+ template <typename T>
353+ Environment::BindingScope<T>::~BindingScope () {
354+ env->set_current_callback_data (env->as_callback_data ());
355+ }
356+
357+ template <typename T>
358+ v8::MaybeLocal<v8::Object> Environment::MakeBindingCallbackData () {
359+ v8::Local<v8::Function> ctor;
360+ v8::Local<v8::Object> obj;
361+ if (!as_callback_data_template ()->GetFunction (context ()).ToLocal (&ctor) ||
362+ !ctor->NewInstance (context ()).ToLocal (&obj)) {
363+ return v8::MaybeLocal<v8::Object>();
364+ }
365+ T* data = new T (this , obj);
366+ // This won't compile if T is not a BaseObject subclass.
367+ CHECK_EQ (data, static_cast <BaseObject*>(data));
368+ data->MakeWeak ();
369+ return obj;
370+ }
371+
340372inline Environment* Environment::GetThreadLocalEnv () {
341373 return static_cast <Environment*>(uv_key_get (&thread_local_env));
342374}
@@ -1115,7 +1147,7 @@ inline v8::Local<v8::FunctionTemplate>
11151147 v8::Local<v8::Signature> signature,
11161148 v8::ConstructorBehavior behavior,
11171149 v8::SideEffectType side_effect_type) {
1118- v8::Local<v8::Object> external = as_callback_data ();
1150+ v8::Local<v8::Object> external = current_callback_data ();
11191151 return v8::FunctionTemplate::New (isolate (), callback, external,
11201152 signature, 0 , behavior, side_effect_type);
11211153}
@@ -1253,7 +1285,7 @@ void Environment::modify_base_object_count(int64_t delta) {
12531285}
12541286
12551287int64_t Environment::base_object_count () const {
1256- return base_object_count_;
1288+ return base_object_count_ - initial_base_object_count_ ;
12571289}
12581290
12591291void Environment::set_main_utf16 (std::unique_ptr<v8::String::Value> str) {
@@ -1313,6 +1345,10 @@ void Environment::set_process_exit_handler(
13131345 }
13141346} // namespace node
13151347
1348+ // These two files depend on each other. Including base_object-inl.h after this
1349+ // file is the easiest way to avoid issues with that circular dependency.
1350+ #include " base_object-inl.h"
1351+
13161352#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
13171353
13181354#endif // SRC_ENV_INL_H_
0 commit comments