99#include " tonic/common/macros.h"
1010#include " tonic/converter/dart_converter.h"
1111#include " tonic/dart_state.h"
12+ #include " tonic/dart_weak_persistent_value.h"
1213#include " tonic/dart_wrapper_info.h"
1314#include " tonic/logging/dart_error.h"
1415
@@ -26,7 +27,7 @@ class DartWrappable {
2627 kNumberOfNativeFields ,
2728 };
2829
29- DartWrappable () : dart_wrapper_(nullptr ) {}
30+ DartWrappable () : dart_wrapper_(DartWeakPersistentValue() ) {}
3031
3132 // Subclasses that wish to expose a new interface must override this function
3233 // and provide information about their wrapper. There is no need to call your
@@ -49,7 +50,9 @@ class DartWrappable {
4950 Dart_Handle CreateDartWrapper (DartState* dart_state);
5051 void AssociateWithDartWrapper (Dart_Handle wrappable);
5152 void ClearDartWrapper (); // Warning: Might delete this.
52- Dart_WeakPersistentHandle dart_wrapper () const { return dart_wrapper_; }
53+ Dart_WeakPersistentHandle dart_wrapper () const {
54+ return dart_wrapper_.value ();
55+ }
5356
5457 protected:
5558 virtual ~DartWrappable ();
@@ -59,11 +62,9 @@ class DartWrappable {
5962 const tonic::DartWrapperInfo& wrapper_info);
6063
6164 private:
62- static void FinalizeDartWrapper (void * isolate_callback_data,
63- Dart_WeakPersistentHandle wrapper,
64- void * peer);
65+ static void FinalizeDartWrapper (void * isolate_callback_data, void * peer);
6566
66- Dart_WeakPersistentHandle dart_wrapper_;
67+ DartWeakPersistentValue dart_wrapper_;
6768
6869 TONIC_DISALLOW_COPY_AND_ASSIGN (DartWrappable);
6970};
@@ -103,22 +104,36 @@ struct DartConverter<
103104 typename std::enable_if<
104105 std::is_convertible<T*, const DartWrappable*>::value>::type> {
105106 static Dart_Handle ToDart (DartWrappable* val) {
106- if (!val)
107+ if (!val) {
107108 return Dart_Null ();
108- if (Dart_WeakPersistentHandle wrapper = val->dart_wrapper ())
109- return Dart_HandleFromWeakPersistent (wrapper);
109+ }
110+ if (Dart_WeakPersistentHandle wrapper = val->dart_wrapper ()) {
111+ auto strong_handle = Dart_HandleFromWeakPersistent (wrapper);
112+ if (!Dart_IsNull (strong_handle)) {
113+ return strong_handle;
114+ }
115+ // After the weak referenced object has been GCed, the handle points to
116+ // Dart_Null(). Fall through create a new wrapper object.
117+ }
110118 return val->CreateDartWrapper (DartState::Current ());
111119 }
112120
113121 static void SetReturnValue (Dart_NativeArguments args,
114122 DartWrappable* val,
115123 bool auto_scope = true ) {
116- if (!val)
124+ if (!val) {
117125 Dart_SetReturnValue (args, Dart_Null ());
118- else if (Dart_WeakPersistentHandle wrapper = val->dart_wrapper ())
119- Dart_SetWeakHandleReturnValue (args, wrapper);
120- else
121- Dart_SetReturnValue (args, val->CreateDartWrapper (DartState::Current ()));
126+ return ;
127+ } else if (Dart_WeakPersistentHandle wrapper = val->dart_wrapper ()) {
128+ auto strong_handle = Dart_HandleFromWeakPersistent (wrapper);
129+ if (!Dart_IsNull (strong_handle)) {
130+ Dart_SetReturnValue (args, strong_handle);
131+ return ;
132+ }
133+ // After the weak referenced object has been GCed, the handle points to
134+ // Dart_Null(). Fall through create a new wrapper object.
135+ }
136+ Dart_SetReturnValue (args, val->CreateDartWrapper (DartState::Current ()));
122137 }
123138
124139 static T* FromDart (Dart_Handle handle) {
0 commit comments