@@ -59,22 +59,30 @@ class Managed : public Foreign {
59
59
isolate->factory ()->NewForeign (reinterpret_cast <Address>(finalizer)));
60
60
Handle <Object> global_handle = isolate->global_handles ()->Create (*handle);
61
61
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 );
65
65
66
66
return handle;
67
67
}
68
68
69
69
private:
70
- static void GCDelete (const v8::WeakCallbackInfo<void >& data) {
70
+ static void ResetWeakAndScheduleGCDelete (
71
+ const v8::WeakCallbackInfo<void >& data) {
71
72
FinalizerWithHandle* finalizer =
72
73
reinterpret_cast <FinalizerWithHandle*>(data.GetParameter ());
73
-
74
+ GlobalHandles::Destroy (finalizer-> global_handle_location );
74
75
Isolate* isolate = reinterpret_cast <Isolate*>(data.GetIsolate ());
75
76
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
+ }
76
82
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 ());
78
86
NativeDelete (finalizer);
79
87
}
80
88
0 commit comments