@@ -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}
@@ -1123,7 +1155,7 @@ inline v8::Local<v8::FunctionTemplate>
11231155 v8::Local<v8::Signature> signature,
11241156 v8::ConstructorBehavior behavior,
11251157 v8::SideEffectType side_effect_type) {
1126- v8::Local<v8::Object> external = as_callback_data ();
1158+ v8::Local<v8::Object> external = current_callback_data ();
11271159 return v8::FunctionTemplate::New (isolate (), callback, external,
11281160 signature, 0 , behavior, side_effect_type);
11291161}
@@ -1261,7 +1293,7 @@ void Environment::modify_base_object_count(int64_t delta) {
12611293}
12621294
12631295int64_t Environment::base_object_count () const {
1264- return base_object_count_;
1296+ return base_object_count_ - initial_base_object_count_ ;
12651297}
12661298
12671299void Environment::set_main_utf16 (std::unique_ptr<v8::String::Value> str) {
@@ -1321,6 +1353,10 @@ void Environment::set_process_exit_handler(
13211353 }
13221354} // namespace node
13231355
1356+ // These two files depend on each other. Including base_object-inl.h after this
1357+ // file is the easiest way to avoid issues with that circular dependency.
1358+ #include " base_object-inl.h"
1359+
13241360#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
13251361
13261362#endif // SRC_ENV_INL_H_
0 commit comments