@@ -59,22 +59,30 @@ class Managed : public Foreign {
5959 isolate->factory ()->NewForeign (reinterpret_cast <Address>(finalizer)));
6060 Handle<Object> global_handle = isolate->global_handles ()->Create (*handle);
6161 finalizer->global_handle_location = global_handle.location ();
62- GlobalHandles::MakeWeak (finalizer-> global_handle_location ,
63- handle->GetFinalizer (), &Managed<CppType>::GCDelete ,
64- v8::WeakCallbackType::kParameter );
62+ GlobalHandles::MakeWeak (
63+ finalizer-> global_handle_location , handle->GetFinalizer (),
64+ &ResetWeakAndScheduleGCDelete, v8::WeakCallbackType::kParameter );
6565
6666 return handle;
6767 }
6868
6969 private:
70- static void GCDelete (const v8::WeakCallbackInfo<void >& data) {
70+ static void ResetWeakAndScheduleGCDelete (
71+ const v8::WeakCallbackInfo<void >& data) {
7172 FinalizerWithHandle* finalizer =
7273 reinterpret_cast <FinalizerWithHandle*>(data.GetParameter ());
73-
74+ GlobalHandles::Destroy (finalizer-> global_handle_location );
7475 Isolate* isolate = reinterpret_cast <Isolate*>(data.GetIsolate ());
7576 isolate->UnregisterFromReleaseAtTeardown (finalizer);
77+ // We need to call GCDelete as a second pass callback because
78+ // it can trigger garbage collection. The first pass callbacks
79+ // are not allowed to invoke V8 API.
80+ data.SetSecondPassCallback (&GCDelete);
81+ }
7682
77- GlobalHandles::Destroy (finalizer->global_handle_location );
83+ static void GCDelete (const v8::WeakCallbackInfo<void >& data) {
84+ FinalizerWithHandle* finalizer =
85+ reinterpret_cast <FinalizerWithHandle*>(data.GetParameter ());
7886 NativeDelete (finalizer);
7987 }
8088
0 commit comments