@@ -53,6 +53,7 @@ using v8::Context;
5353using v8::EscapableHandleScope;
5454using v8::FunctionCallbackInfo;
5555using v8::Global;
56+ using v8::HandleScope;
5657using v8::Int32;
5758using v8::Integer;
5859using v8::Isolate;
@@ -73,8 +74,10 @@ namespace {
7374
7475class CallbackInfo {
7576 public:
77+ ~CallbackInfo ();
78+
7679 static inline void Free (char * data, void * hint);
77- static inline CallbackInfo* New (Isolate* isolate ,
80+ static inline CallbackInfo* New (Environment* env ,
7881 Local<ArrayBuffer> object,
7982 FreeCallback callback,
8083 char * data,
@@ -84,9 +87,10 @@ class CallbackInfo {
8487 CallbackInfo& operator =(const CallbackInfo&) = delete ;
8588
8689 private:
90+ static void CleanupHook (void * data);
8791 static void WeakCallback (const WeakCallbackInfo<CallbackInfo>&);
8892 inline void WeakCallback (Isolate* isolate);
89- inline CallbackInfo (Isolate* isolate ,
93+ inline CallbackInfo (Environment* env ,
9094 Local<ArrayBuffer> object,
9195 FreeCallback callback,
9296 char * data,
@@ -95,6 +99,7 @@ class CallbackInfo {
9599 FreeCallback const callback_;
96100 char * const data_;
97101 void * const hint_;
102+ Environment* const env_;
98103};
99104
100105
@@ -103,31 +108,53 @@ void CallbackInfo::Free(char* data, void*) {
103108}
104109
105110
106- CallbackInfo* CallbackInfo::New (Isolate* isolate ,
111+ CallbackInfo* CallbackInfo::New (Environment* env ,
107112 Local<ArrayBuffer> object,
108113 FreeCallback callback,
109114 char * data,
110115 void * hint) {
111- return new CallbackInfo (isolate , object, callback, data, hint);
116+ return new CallbackInfo (env , object, callback, data, hint);
112117}
113118
114119
115- CallbackInfo::CallbackInfo (Isolate* isolate ,
120+ CallbackInfo::CallbackInfo (Environment* env ,
116121 Local<ArrayBuffer> object,
117122 FreeCallback callback,
118123 char * data,
119124 void * hint)
120- : persistent_(isolate, object),
125+ : persistent_(env-> isolate () , object),
121126 callback_(callback),
122127 data_(data),
123- hint_(hint) {
128+ hint_(hint),
129+ env_(env) {
124130 ArrayBuffer::Contents obj_c = object->GetContents ();
125131 CHECK_EQ (data_, static_cast <char *>(obj_c.Data ()));
126132 if (object->ByteLength () != 0 )
127133 CHECK_NOT_NULL (data_);
128134
129135 persistent_.SetWeak (this , WeakCallback, v8::WeakCallbackType::kParameter );
130- isolate->AdjustAmountOfExternalAllocatedMemory (sizeof (*this ));
136+ env->AddCleanupHook (CleanupHook, this );
137+ env->isolate ()->AdjustAmountOfExternalAllocatedMemory (sizeof (*this ));
138+ }
139+
140+
141+ CallbackInfo::~CallbackInfo () {
142+ persistent_.Reset ();
143+ env_->RemoveCleanupHook (CleanupHook, this );
144+ }
145+
146+
147+ void CallbackInfo::CleanupHook (void * data) {
148+ CallbackInfo* self = static_cast <CallbackInfo*>(data);
149+
150+ {
151+ HandleScope handle_scope (self->env_ ->isolate ());
152+ Local<ArrayBuffer> ab = self->persistent_ .Get (self->env_ ->isolate ());
153+ CHECK (!ab.IsEmpty ());
154+ ab->Detach ();
155+ }
156+
157+ self->WeakCallback (self->env_ ->isolate ());
131158}
132159
133160
@@ -391,7 +418,7 @@ MaybeLocal<Object> New(Environment* env,
391418 }
392419 MaybeLocal<Uint8Array> ui = Buffer::New (env, ab, 0 , length);
393420
394- CallbackInfo::New (env-> isolate () , ab, callback, data, hint);
421+ CallbackInfo::New (env, ab, callback, data, hint);
395422
396423 if (ui.IsEmpty ())
397424 return MaybeLocal<Object>();
0 commit comments