@@ -287,6 +287,10 @@ inline void Environment::AssignToContext(v8::Local<v8::Context> context,
287287 // Used by Environment::GetCurrent to know that we are on a node context.
288288 context->SetAlignedPointerInEmbedderData (
289289 ContextEmbedderIndex::kContextTag , Environment::kNodeContextTagPtr );
290+ // Used to retrieve bindings
291+ context->SetAlignedPointerInEmbedderData (
292+ ContextEmbedderIndex::KBindingListIndex, &(this ->bindings_ ));
293+
290294#if HAVE_INSPECTOR
291295 inspector_agent ()->ContextCreated (context, info);
292296#endif // HAVE_INSPECTOR
@@ -318,55 +322,74 @@ inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
318322
319323inline Environment* Environment::GetCurrent (
320324 const v8::FunctionCallbackInfo<v8::Value>& info) {
321- return GetFromCallbackData (info. Data () );
325+ return BindingDataBase::Unwrap<BindingDataBase> (info)-> env ( );
322326}
323327
324328template <typename T>
325329inline Environment* Environment::GetCurrent (
326330 const v8::PropertyCallbackInfo<T>& info) {
327- return GetFromCallbackData (info. Data () );
331+ return BindingDataBase::Unwrap<BindingDataBase> (info)-> env ( );
328332}
329333
330- Environment* Environment::GetFromCallbackData (v8::Local<v8::Value> val) {
331- DCHECK (val->IsObject ());
332- v8::Local<v8::Object> obj = val.As <v8::Object>();
333- DCHECK_GE (obj->InternalFieldCount (),
334- BaseObject::kInternalFieldCount );
335- Environment* env = Unwrap<BaseObject>(obj)->env ();
336- DCHECK (env->as_callback_data_template ()->HasInstance (obj));
337- return env;
334+ inline BindingDataBase::BindingDataBase (Environment* env,
335+ v8::Local<v8::Object> target)
336+ : BaseObject(env, target) {}
337+
338+ template <typename T, typename U>
339+ inline T* BindingDataBase::Unwrap (const v8::PropertyCallbackInfo<U>& info) {
340+ return Unwrap<T>(info.GetIsolate ()->GetCurrentContext (), info.Data ());
338341}
339342
340343template <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);
344+ inline T* BindingDataBase::Unwrap (
345+ const v8::FunctionCallbackInfo<v8::Value>& info) {
346+ return Unwrap<T>(info.GetIsolate ()->GetCurrentContext (), info.Data ());
347+ }
346348
347- // No nesting allowed currently.
348- CHECK_EQ (env->current_callback_data (), env->as_callback_data ());
349- env->set_current_callback_data (callback_data);
349+ template <typename T>
350+ inline T* BindingDataBase::Unwrap (v8::Local<v8::Context> context,
351+ v8::Local<v8::Value> val) {
352+ CHECK (val->IsUint32 ());
353+ uint32_t index = val.As <v8::Uint32>()->Value ();
354+ std::vector<BindingDataBase*>* list =
355+ static_cast <std::vector<BindingDataBase*>*>(
356+ context->GetAlignedPointerFromEmbedderData (
357+ ContextEmbedderIndex::KBindingListIndex));
358+ CHECK_GT (list->size (), index);
359+ T* result = static_cast <T*>(list->at (index));
360+ return result;
350361}
351362
352363template <typename T>
353- Environment::BindingScope<T>::~BindingScope () {
354- env->set_current_callback_data (env->as_callback_data ());
364+ inline v8::Local<v8::Uint32> BindingDataBase::New (
365+ Environment* env,
366+ v8::Local<v8::Context> context,
367+ v8::Local<v8::Object> target) {
368+ T* data = new T (env, target);
369+ // This won't compile if T is not a BindingDataBase subclass.
370+ BindingDataBase* item = static_cast <BindingDataBase*>(data);
371+ std::vector<BindingDataBase*>* list =
372+ static_cast <std::vector<BindingDataBase*>*>(
373+ context->GetAlignedPointerFromEmbedderData (
374+ ContextEmbedderIndex::KBindingListIndex));
375+ size_t index = list->size ();
376+ list->push_back (item);
377+ return v8::Integer::NewFromUnsigned (env->isolate (), index).As <v8::Uint32>();
355378}
356379
357380template <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 ;
381+ Environment::BindingScope<T>::BindingScope(Environment* env,
382+ v8::Local<v8::Context> context,
383+ v8::Local<v8::Object> target)
384+ : env(env) {
385+ v8::Local<v8::Uint32> index = BindingDataBase::New<T>(env, context, target);
386+ data = BindingDataBase::Unwrap<T>(context, index );
387+ env-> set_current_callback_data (index);
388+ }
389+
390+ template < typename T>
391+ Environment::BindingScope<T>:: ~BindingScope () {
392+ env-> set_current_callback_data (env-> default_callback_data ()) ;
370393}
371394
372395inline Environment* Environment::GetThreadLocalEnv () {
@@ -1085,7 +1108,7 @@ inline v8::Local<v8::FunctionTemplate>
10851108 v8::Local<v8::Signature> signature,
10861109 v8::ConstructorBehavior behavior,
10871110 v8::SideEffectType side_effect_type) {
1088- v8::Local<v8::Object > external = current_callback_data ();
1111+ v8::Local<v8::Value > external = current_callback_data ();
10891112 return v8::FunctionTemplate::New (isolate (), callback, external,
10901113 signature, 0 , behavior, side_effect_type);
10911114}
@@ -1276,6 +1299,7 @@ void Environment::set_process_exit_handler(
12761299 }
12771300 ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES (V)
12781301 ENVIRONMENT_STRONG_PERSISTENT_VALUES (V)
1302+ ENVIRONMENT_CALLBACK_DATA (V)
12791303#undef V
12801304
12811305 inline v8::Local<v8::Context> Environment::context () const {
0 commit comments